# shop.py
from pyppeteer.page import Page
from pyppeteer_stealth import stealth
from lxml import etree
from config import *
from tool import *
from api import *
from sql import sqlseverDB
import requests,concurrent.futures
import math,traceback,logging,inspect
import shutil,string

class Shop:
    def __init__(self,basic_info):
        self.basic_info=basic_info
        self.basic_info['PingTai']='shopee'
        self.shopid=basic_info['shopid']
        self.bid=basic_info['BrowserID']
        self.dpName=basic_info['DpName']
        self.userName = basic_info['UserName']
        self.password = basic_info['Password']
        self.yybm=basic_info['YYBM']
        self.gname=basic_info['GroupName']
        self.sjbm=basic_info['SJBM']
        self.session=requests.session()
        self.ck=None
        self.SPC_CDS=None
        self.shopid=None
        self.ms = sqlseverDB('{SQL Server}', SQL_SERVER, 'sumaitongpol', SQL_USER, SQL_PWD)

    async def close_browser(self,bro):
        bid=self.bid
        bname=self.dpName
        task_id=self.task_id
        aff_close=tms.ExecNoQuery('update taskstatus set is_on=0 where bid=? and task_id=?',(bid,task_id))
        rs= tms.ExecQuery('select count(*) from taskstatus where bid=? and task_id!=? and is_on=1',(bid,task_id))
        
        if rs[0][0]==0:
            try:
                await bro.close()
                logging.info(f'店铺:{bname},{bid},关闭浏览器成功,记录状态:{aff_close}')
            except Exception as e:
                logging.error(f'店铺:{bname},{bid},关闭浏览器失败,记录状态:{aff_close}')

            # try:
            #     await bro.disconnect()
            #     logging.info(f'店铺:{bname},{bid},断开接管')
            # except Exception as e:
            #     logging.error(f'店铺:{bname},{bid},断开接管失败 =>{e}')
        else:
            logging.info(f'店铺:{bname},{bid},有其他 {rs[0][0]} 个任务,正在运行,稍后关闭')

    async def check_login(self,page:Page):
        wait_count=0
        no_login_count=0
        task_id=self.task_id
        task_name=Task_Name_dict[task_id]

        while True:
            now_time_str=datetime.datetime.now()
            zds=['iscl','task_id','task_name','BID','loginTime','pintai','bname','gname','des']
            params=[0,task_id,task_name,self.bid,now_time_str,'shopee',self.dpName,self.gname]
            zd_on=['BID']
            if MAX_WAIT and wait_count>MAX_WAIT:
                err_des='等待时间过长'
                params.append(err_des)
                aff=self.ms.merge_into('ErrBid',zds,params,zd_on)
                logging.info(f'店铺:{self.dpName},bid:{self.bid},{err_des},已登记错误:{aff}')
                await page.close()
                return
            try:
                acc=await page.xpath('//div[@class="subaccount-info"]')
                no_login=await page.xpath('//input[@name="loginKey"]')
                el_ck_phone=await page.xpath('//div[@class="verify-container"]//button/span[text()=" Cancel "]')
                cot= await page.content()
                if 'Halaman Tidak Tersedia' in cot  or 'verify/captcha' in page.url:
                    err_des='登录跳转到失败页面'
                    params.append(err_des)
                    aff=self.ms.merge_into('ErrBid',zds,params,zd_on)
                    logging.info(f'店铺:{self.dpName},bid:{self.bid},{err_des},已登记错误:{aff}')
                    await page.close()
                    return
                
                if el_ck_phone:
                    #手机验证
                    await el_ck_phone[0].click({'delay':200})
                    await asyncio.sleep(3)

                if no_login:
                    if no_login_count>=3:
                        err_des='卡在登录页面'
                        params.append(err_des)
                        aff=self.ms.merge_into('ErrBid',zds,params,zd_on)
                        logging.info(f'店铺:{self.dpName},bid:{self.bid},{err_des},已登记错误:{aff}')
                        await page.close()
                        return
                    logging.info(f'店铺:{self.dpName},账号未登录,进行登录')
                    if not self.userName or not self.password:
                        err_des='没有账号密码'
                        params.append(err_des)
                        aff=self.ms.merge_into('ErrBid',zds,params,zd_on)
                        logging.info(f'店铺:{self.dpName},bid:{self.bid},{err_des},已登记错误:{aff}')
                        await page.close()
                        return
                    await repeat_reload(page)
                    await asyncio.sleep(10)
                    cot=await page.content()
                    el_isusername=etree.HTML(cot).xpath('//input[@name="loginKey"]/@value')
                    haspad=False
                    if el_isusername:
                        cusername=el_isusername[0]
                        if cusername:
                            haspad=True
                    if not haspad:
                        await page.type('input[name=loginKey]',self.userName,{'delay': 120})
                        await page.type('input[name=password]',self.password,{'delay': 120})
                    await page.waitFor(1000)
                    btn_login=(await page.xpath('//form/button[1]'))[0]
                    await btn_login.click()
                    await asyncio.sleep(15)
                    no_login_count+=1
                    
                if acc:
                    logging.info(f'店铺:《{self.dpName}》,{self.bid},已登录')
                    return page
                
                wait_count+=1
                    
            except Exception as e:
                logging.info(e)
                wait_count+=1
            await asyncio.sleep(2)
    
    async def get_ck(self,isforce=0,url=None):

        async def intercept_response(res):
            if "seller.shopee.co.id/api/selleraccount/shop_info/" in res.request.url:
                try:
                    json_data =await res.json()
                    self.shopid=json_data['data']['shop_id']
                    logging.info(f'{self.dpName},获取到Shopid:{self.shopid}')
                except Exception as e:
                    logging.error(e)

        if self.ck and not isforce:
            return
        browser=await openSunBrowser(self.basic_info,self.task_id)
        if not browser:
            return '启动浏览器失败'
        page=await browser.newPage()
        page.on('response', lambda rep: asyncio.ensure_future(intercept_response(rep)))
        if url is None:
            url='https://seller.shopee.co.id/datacenter/product/performance'
        await repeat_goto(page,url)
        
        page=await self.check_login(page)
        if not page:
            await self.close_browser(browser)
            return '账户未登录'
        self.SPC_CDS,self.ck=await get_ck_and_spc_cds(page)
        while True:
            if self.shopid:
                break
            await asyncio.sleep(1)
        logging.info(f'店铺:《{self.dpName}》,获取cookie成功,同时获取店铺SPDC:{self.SPC_CDS},店铺Shopid:{self.shopid}')
        await page.close()
        await self.close_browser(browser)
         
    async def yb_get_Homeinfo(self):
        '''采集店铺首页'''
        browser = await openSunBrowser(self.basic_info,self.task_id)
        #browser=await openChrome()
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        page=await browser.newPage()
        url=f'https://seller.shopee.co.id/'
        await repeat_goto(page,url)
        sss=await self.check_login(page)
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        await asyncio.sleep(6)
        zds=[]
        params=[]
        #获取 To Do List 8个参数值
        shopid=await js_req_shopid(page,self.basic_info)

        if not shopid:
            await self.close_browser(browser)
            return {'code':-3,'msg':'获取Shopid失败'}

        res_to_do_list=await get_to_do_list(page,self.basic_info)
        if res_to_do_list:
            zds.extend(['unpaid','to_process_shipment','processed_shipment','pending_cancellation',
                'pending_return','banned_products','sold_out_products','to_join_bidding'])
            params.extend(res_to_do_list)
        else:
            logging.info(f'店铺:{self.dpName},{self.bid},获取《To Do List》内容失败')

        #获取 Business Insights 8个参数
        res_business_insights=await get_business_insights(page,self.basic_info)
        if res_business_insights:
            zds.extend(['visitors','visitors_trend','page_views','page_views_trend',
                 'orders','orders_trend','conversion_rate','conversion_rate_trend'])
            params.extend(res_business_insights)
        else:
            logging.info(f'店铺:{self.dpName},{self.bid},获取《Business Insights》内容失败')
        
        #获取 Performance 4个参数
        res_performance=await get_performance(page,self.basic_info)
        if res_business_insights:
            zds.extend(['Non_fulfilment_Rate','Late_Shipment_Rate','Preparation_Time','My_Penalty'])
            params.extend(res_performance)
        else:
            logging.info(f'店铺:{self.dpName},{self.bid},获取《Performance》内容失败')

        if not zds:
            logging.info(f'店铺:{self.dpName},{self.bid},获取首页内容失败')
            return {'code':-3,'msg':'获取首页内容失败'}
        else:
            bid=self.bid
            dpname=self.dpName
            yybm=self.yybm
            gname=self.gname
            login_url='https://seller.shopee.co.id/'
            now_time= datetime.datetime.now()
            zds=['SJBM','shopName','YYBM','GroupName','shopid','bid','longinUrl','userName','password']+zds
            params=[self.sjbm,dpname,yybm,gname,shopid,bid,login_url,self.userName,self.password]+params
            params.append(now_time)
            
            rs=self.ms.ExecQuery('select count(*) from ShopHome where shopid=?',(shopid,))
            if rs[0][0]>0:
                zds.append('update_time')
                zdstr=','.join([f'{zd}=?' for zd in zds])
                sqlstr=f'update [ShopHome] set {zdstr} where shopid=?'
                aff=self.ms.ExecNoQuery(sqlstr,params+[shopid])
                await page.close()
                await self.close_browser(browser)
                return {'code':0,'msg':'更新','aff':aff}
            else:
                zds=zds+['update_time','upload_time']
                params.append(now_time)
                zdstr=','.join(zds)
                wstr=','.join(['?' for _ in params])
                sqlstr=f'insert into ShopHome({zdstr}) values({wstr})'
                aff=self.ms.ExecNoQuery(sqlstr,params)
                await page.close()
                await self.close_browser(browser)
                return {'code':0,'msg':'新增','aff':aff}

    def upload_product(self,data):
        bid,shopid,itemid,purl,pname,rcode,ph_itemid,MainImage,delist,skuid,sku1,sku2,Quantity=data
        rs=self.ms.ExecQuery('select itemid from YNBigData where code=?',(rcode,))
        
        if len(rs)==0:
            zds=['ADSID','shopID','itemID','Purl','Title','code','PHItemid','MainImage','Delist','SkuID','sku1','sku2',
                 'Quantity','shangjiabianma']
            params=[bid,shopid,itemid,purl,pname,rcode,ph_itemid,MainImage,delist,skuid,sku1,sku2,Quantity,self.sjbm]
            zdstr=','.join(zds)
            wen_str=','.join(['?' for _ in params])
            sqlstr=f'''insert into YNBigData({zdstr}) 
                        values({wen_str})'''
            aff=self.ms.ExecNoQuery(sqlstr,params)
            return rcode,aff,'新增itemid'

        else:
            all_old_itemids=[r[0] for r in rs]
            if itemid in all_old_itemids:
                rs_skur=self.ms.ExecQuery('select count(*) from YNBigData where skuid=?',(skuid,))
                if rs_skur[0][0]==0:
                    zds=['ADSID','shopID','itemID','Purl','Title','code','PHItemid','MainImage','Delist','SkuID','sku1','sku2',
                        'Quantity','shangjiabianma']
                    params=[bid,shopid,itemid,purl,pname,rcode,ph_itemid,MainImage,delist,skuid,sku1,sku2,Quantity,self.sjbm]
                    zdstr=','.join(zds)
                    wen_str=','.join(['?' for _ in params])
                    sqlstr=f'''insert into YNBigData({zdstr}) 
                                values({wen_str})'''
                    aff=self.ms.ExecNoQuery(sqlstr,params)
                    return rcode,aff,f'同itemid新增sku{skuid}'
                
                else:
                    zds=['ADSID','shopID','itemID','Purl','Title','code','PHItemid','MainImage',
                        'Delist','SKU1','sku2','Quantity']
                    params=[bid,shopid,itemid,purl,pname,rcode,ph_itemid,MainImage,delist,sku1,sku2,Quantity,skuid]

                    zdstr=','.join([f'{zd}=?' for zd in zds])
                    sqlstr=f'''update YNBigData 
                                set {zdstr}
                                where skuid=?'''
                    aff=self.ms.ExecNoQuery(sqlstr,params)
                    return rcode,aff,f'同itemid更新sku{skuid}'
            
            else:
                if sku2:
                    rs_skur=self.ms.ExecQuery('select skuid,Quantity from YNBigData where code=? and sku1=? and sku2=?',(rcode,sku1,sku2))
                else:
                    rs_skur=self.ms.ExecQuery('select skuid,Quantity from YNBigData where code=? and sku1=? and (sku2 is null or sku2=?)',
                                              (rcode,sku1,''))
                
                if len(rs_skur)==0:
                    zds=['ADSID','shopID','itemID','Purl','Title','code','PHItemid','MainImage','Delist','SkuID','sku1','sku2',
                        'Quantity','shangjiabianma']
                    params=[bid,shopid,itemid,purl,pname,rcode,ph_itemid,MainImage,delist,skuid,sku1,sku2,Quantity,self.sjbm]
                    zdstr=','.join(zds)
                    wen_str=','.join(['?' for _ in params])
                    sqlstr=f'''insert into YNBigData({zdstr}) 
                                values({wen_str})'''
                    aff=self.ms.ExecNoQuery(sqlstr,params)
                    return rcode,aff,f'不同itemid新增sku{skuid}'
                else:
                    old_skuid,old_sold=rs_skur[0]
                    zds=['ADSID','shopID','itemID','Purl','Title','code','PHItemid','MainImage',
                        'Delist','SKU1','sku2','Quantity']
                    params=[bid,shopid,itemid,purl,pname,rcode,ph_itemid,MainImage,delist,sku1,sku2,Quantity+old_sold,old_skuid]

                    zdstr=','.join([f'{zd}=?' for zd in zds])
                    sqlstr=f'''update YNBigData 
                                set {zdstr}
                                where skuid=?'''
                    aff=self.ms.ExecNoQuery(sqlstr,params)
                    return rcode,aff,f'不同itemid更新sku{old_skuid}'

    async def yb_get_product(self):
        '''异步大数据出单'''

        browser = await openSunBrowser(self.basic_info,self.task_id)
        #browser=await openChrome()
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        page=await browser.newPage()
        url=f'https://seller.shopee.co.id/datacenter/product/performance'
        await repeat_goto(page,url)
        sss=await self.check_login(page)
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        
        datas=await get_all_xp_order(page,self.basic_info)
        with concurrent.futures.ThreadPoolExecutor(max_workers=5) as t0:

            tasks=[t0.submit(self.upload_product,dataline) for dataline in datas]
            suc=0
            for t in concurrent.futures.as_completed(tasks):
                try:
                    res_rocde,aff,msg=t.result()
                    logging.info(f'店铺《{self.dpName}》,{msg},随机码:{res_rocde},状态:{aff}')
                    if aff>0:
                        suc+=1
                except Exception as e:
                    logging.error(f'店铺:{self.dpName},{self.bid},存储数据线程错误 => {e}')
                    traceback.print_exc()
                
        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':f'执行成功','aff':suc}

    async def yb_cteate_ad(self):
        '''发布广告'''
        bid=self.bid
        browser=await openSunBrowser(self.basic_info,self.task_id)
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        suc=0
        for j in range(10):
            page=await browser.newPage()
            await repeat_goto(page,'https://seller.shopee.co.id/portal/marketing/pas/product/create?source_page_id=1')
            sss=await self.check_login(page)
            if not sss:
                await self.close_browser(browser)
                return {'code':-2,'msg':'账户登录失败'}
            
            await check_tc(page,'//div[@class="FULMadiY5u"]//div[text()="Maybe Later"]')
            logging.info(f'bid:{bid},第一步,开始创建新广告...')
            await asyncio.sleep(10)
            logging.info(f'bid:{bid},第二步,开始设置广告预算...')
            radio_btns=await wait_one_xpath(page,'//label[@class="eds-radio yes-limit"]')
            await radio_btns[0].click({'dealy':2000})
            await asyncio.sleep(3)
            await page.type('input.eds-input__input','11000',{'delay':100})

            logging.info(f'bid:{bid},第三步,Product Selection...')

            elps1=await page.xpath('//div[text()="Manually select products"]/..')
            await elps1[0].click({'delay':1000})
            await asyncio.sleep(3)
            logging.info(f'bid:{bid},第四步,开始添加产品...')
            #await page.click('.add-btn',{'delay':2000})
            await page.click('.add-product',{'delay':200})
            await asyncio.sleep(15)

            await wait_one_xpath(page,'//table[@class="eds-table__header"]')
            #trs=await page.xpath('//tr[@class="eds-table__row"]')
            trs=await page.xpath('//tr[contains(@class,"eds-table__row")]')
            
            if len(trs)==0:
                logging.info(f'bid:{bid},没有新产品结束新建广告')
                await page.close()
                await self.close_browser(browser)
                return {'code':0,'msg':'没有新产品结束新建广告','aff':0}
            select_tr=None
            logging.info(f'bid:{bid},正在选择产品')
            dj_count=0
            while True:
                if select_tr:
                    break
                for tr in trs:
                    jccc=await tr.xpath('.//p[@class="promotion-ongoing product-decorator"]')
                    jccc2=await tr.xpath('.//div[@class="tags-container"]//div[text()="GMV Max"]')
                    jccc3=await tr.xpath('.//a[@class="existing-ads-text"]')
                    if jccc or jccc2 or jccc3:
                        continue
                    else:
                        logging.info(f'bid:{bid},找到产品')
                        select_tr=tr
                        break
                
                if not select_tr:
                    if len(trs)<5:
                        logging.info(f'bid:{bid},没有新产品结束新建广告')
                        await page.close()
                        await self.close_browser(browser)
                        return {'code':0,'msg':'执行成功','aff':suc}
                    btn_nextbtn=await page.JJ('.eds-pager__button-next')
                    if btn_nextbtn:
                        await page.click('.eds-pager__button-next',{'delay':500})
                        await asyncio.sleep(1)
                        #trs=await page.xpath('//tr[@class="eds-table__row"]')
                        trs=await page.xpath('//tr[contains(@class,"eds-table__row")]')
                    else:
                        logging.info(f'bid:{bid},没有新产品结束新建广告')
                        await page.close()
                        await self.close_browser(browser)
                        return {'code':0,'msg':'执行成功','aff':suc}
                
                if dj_count>30:
                    logging.info(f'bid:{bid},翻页超过30次退出')
                    await page.close()
                    await self.close_browser(browser)
                    return {'code':0,'msg':'执行成功','aff':suc}
                
                dj_count+=1
            
            btn_stb=await select_tr.xpath('.//span[@class="eds-radio__indicator"]')
            await btn_stb[0].click({'delay':500})
            await asyncio.sleep(1)

            el_footbtndivs=await page.xpath('//div[@class="eds-modal__footer-buttons"]')
            for el_footbtndiv in  el_footbtndivs:
                try:
                    el_btnqr=await el_footbtndiv.xpath('./button[2]')
                    if el_btnqr:
                        await el_btnqr[0].click({'delay':500})
                        await asyncio.sleep(0.5) 
                except Exception as e:
                    logging.error(e)
            await asyncio.sleep(3) 
            logging.info(f'bid:{bid},第五步,设置关键词...')

            for ccj in range(5):
                try:
                    elps1=await page.xpath('//div[text()="Configure all bidding settings manually"]/..')
                    await elps1[0].click({'delay':500})
                    await asyncio.sleep(3)
                except Exception as e:
                    logging.error(f'bid:{bid},切换到Manual,错误 =>{e}')
                
                btn_adkw=await page.xpath('//div[@class="keyword-actions"]/a[@class="add-button"]')
                if btn_adkw:
                    break
                await asyncio.sleep(2)
            
            if not btn_adkw:
                logging.info(f'bid:{bid},点击添加关键词未出现,跳过...')
                continue
            await btn_adkw[0].click({'delay':500})
            await asyncio.sleep(3)

            el_kws=await page.xpath('//div[@class="keyword"]')
            await asyncio.sleep(2)
            if not el_kws:
                await asyncio.sleep(5)
                el_kws=await page.xpath('//div[@class="keyword"]')
            kj=1
            for el_kw in el_kws:
                ad_kw=await page.evaluate('(el) => el.textContent', el_kw)
                ad_kw=ad_kw.strip()
                ad_kw_num=len(ad_kw.split())
                
                if ad_kw_num>2:
                    el_add_click=await el_kw.xpath('./../../../td[last()]//a[1]')
                    if el_add_click:
                        await el_add_click[0].click({'delay':200})
                        logging.info(f'店铺:《{self.dpName}》,{self.bid},第{j}个广告,第{kj}个广告词:《{ad_kw}》,单词数量:{ad_kw_num},点击添加')
                        await asyncio.sleep(0.1)
                else:
                    logging.info(f'店铺:《{self.dpName}》,{self.bid},第{j}个广告,第{kj}个广告词:《{ad_kw}》,单词数量:{ad_kw_num},跳过添加')
                kj+=1

            # add_all_kw=await page.xpath('//div[@class="table-section table-section-bg"]//a[@class="add-button"]')
            # await add_all_kw[0].click({'delay':500})
            # await asyncio.sleep(3)

            el_footbtndivs=await page.xpath('//div[@class="eds-modal__footer-buttons"]')
            el_btnqr=await el_footbtndivs[0].xpath('./button[2]')
            await el_btnqr[0].click({'delay':500})
            await asyncio.sleep(5)
            ckallkw=await page.xpath('//table[@class="eds-table__header"]//th[1]//label[@class="eds-checkbox"]')
            await ckallkw[0].click({'delay':500})

            await asyncio.sleep(3)
            logging.info(f'bid:{bid},第六步设置bid price...')
            elbid=await page.xpath('//div[@class="keyword-actions"]/div[1]/div[1]')
            await elbid[0].click()
            await asyncio.sleep(3)
            el_editppp=await page.xpath('//div[@class="batch-edit-bid-price"]/form[1]/div[3]')
            await el_editppp[0].click({'delay':200})

            await asyncio.sleep(3)
            el_iptppp=await el_editppp[0].xpath('.//input[@class="eds-input__input"]')
            await el_iptppp[0].type('300',{'delay':100})

            el_footbtndivs=await page.xpath('//div[@class="actions"]')
            el_btnqr=await el_footbtndivs[1].xpath('./button[2]')
            await el_btnqr[0].click({'delay':200})
            await asyncio.sleep(3)

            logging.info(f'bid:{bid},第七步设置Discovery...')
            el_daily_discover_ipt=await page.xpath('//div[text()="Daily Discover"]/../../td[3]//input[1]')
            await el_daily_discover_ipt[0].type('150',{'delay':200})
            await asyncio.sleep(2)
            el_also_like_ipt=await page.xpath('//div[text()="You May Also Like"]/../../td[3]//input[1]')
            await el_also_like_ipt[0].type('150',{'delay':200})
            await asyncio.sleep(2)

            logging.info(f'bid:{bid},第八步设置advancing Setting...')
            el_adv=await page.xpath('//div[@class="advanced-settings-content"]/span[@class="click-area"]')
            await el_adv[0].click({'delay':200})
            await asyncio.sleep(2)
            
            el_setccc=await page.xpath('//div[@class="advanced-settings-content"]//div[@class="setting-item"]/div[1]')
            await el_setccc[0].click({'delay':200})
            await asyncio.sleep(1)
            await el_setccc[-1].click({'delay':200})
            await asyncio.sleep(1)

            el_footbtndivs=await page.xpath('//div[@class="advanced-settings-content"]//div[@class="footer"]')
            el_btnqr=await el_footbtndivs[0].xpath('./button[2]')
            await el_btnqr[0].click({'delay':200})

            await asyncio.sleep(3)
            logging.info(f'bid:{bid},第九步,提交广告')
            el_footbtndivs=await page.xpath('//div[@class="bottom-container"]')
            el_btnqr=await el_footbtndivs[0].xpath('./button[2]')
            await el_btnqr[0].click({'delay':1000})
        
            await asyncio.sleep(15)
            logging.info(f'bid:{bid},成功发布第{j+1}个广告')
            await page.close()
            suc+=1
        await self.close_browser(browser)
        return {'code':0,'msg':'执行成功','aff':suc}
    
    async def yb_delete_product(self):
        '''删除店铺全部产品'''
        browser=await openSunBrowser(self.basic_info,self.task_id)
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        
        page=await browser.newPage()
        lastpg=False
        aff=0
        pro_url_path='https://seller.shopee.co.id/portal/product/list'
        pro_lxnames=['/live/all','/reviewing','/unpublished/unlisted','/unpublished/draft']

        for pro_lxname in  pro_lxnames:
            purl=f'{pro_url_path}{pro_lxname}'
            await repeat_goto(page,purl)
            sss=await self.check_login(page)
            if not sss:
                await self.close_browser(browser)
                return {'code':-2,'msg':'账户登录失败'}
            await asyncio.sleep(20)
            await wait_one_xpath(page,'//div[@class="tabs__tab"]')
            cot=await page.content()

            livetxt=etree.HTML(cot).xpath('//div[@class="list-header-title"]/text()')[0]
            allpro_count=int(livetxt.replace('products','').replace('product','').replace('.','').strip())
            logging.info(f'{self.dpName},{self.bid},{pro_lxname},还剩{allpro_count}个产品未删除')
            max_ppp=math.ceil(allpro_count/12)
            if pro_lxname in ['/unpublished/unlisted','/unpublished/draft']:
                max_ppp=math.ceil(allpro_count/20)
            for ppp in range(max_ppp):
                logging.info(f'{self.dpName},{self.bid},{pro_lxname},正在删除第 {ppp+1} 页,共{max_ppp}页')
                await repeat_goto(page,purl)
                
                await asyncio.sleep(5)
                await wait_one_xpath(page,'//div[@class="tabs__tab"]')

                el_tc=await page.xpath('//div[@class="eds-modal__content eds-modal__content--medium"]')
                if el_tc:
                    logging.info(f'出现弹窗...')
                    el_btn_close=await el_tc[0].xpath('.//button[1]')
                    try:
                        await el_btn_close[0].click({'delay':200})
                    except Exception as e:
                        logging.info(e)
                await check_tc(page,'//div[@class="FULMadiY5u"]//div[text()="Maybe Later"]')

                el_ckpro=await wait_one_xpath(page,'//div[@class="eds-table__main-header"]/table[1]/thead[1]/tr[1]/th[1]//label[1]')
                await el_ckpro[0].click(options={'delay':1000})
                await asyncio.sleep(5)

                #el_elist_btn=await page.xpath('//button[@class="delete-button eds-button eds-button--normal"]')
                el_elist_btn=await page.xpath('//span[text()="Delete"]')

                try:
                    await el_elist_btn[0].click({'delay':1000})
                except Exception as e:
                    logging.info(e)

                await asyncio.sleep(5)

                el_div_pop_btns=await wait_one_xpath(page,'//div[@class="eds-modal"]//div[@class="eds-modal__footer-buttons"]')
                el_qr_btn=await el_div_pop_btns[0].xpath('./button[2]')
                await el_qr_btn[0].click()
                await asyncio.sleep(5)
                aff+=12
                if lastpg:
                    break
            
        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':'执行成功','aff':aff}

    async def yb_download_probb(self):
        '''下载报表详情'''

        #判断是否已经加入任务表
        ad_task_added=self.basic_info['isBBAdID']
        if ad_task_added==1:
            rs=self.ms.ExecQuery('select count(*) from campaign where bid=? and is_download_bb=0 and is_on=1',(self.bid,))
            if rs[0][0]==0:
                logging.info(f'店铺:《{self.dpName}》,{self.bid},今日所有广告详情报表都已下载完毕')
                return {'code':0,'msg':'今日所有广告详情报表都已下载完毕','aff':0}
        

        browser=await openSunBrowser(self.basic_info,self.task_id)
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        page=await browser.newPage()
        url=f'https://seller.shopee.co.id/portal/marketing/pas/index'
        await repeat_goto(page,url)
        sss=await self.check_login(page)
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}


        await wait_one_xpath(page,'//div[@class="export-button"]',max_wait=120)
        await asyncio.sleep(10)
        await wait_tc_xpath(page)

        if ad_task_added==0:
            logging.info(f'店铺:《{self.dpName}》,{self.bid},广告报表任务未增加到《campaign》,先进行增加操作...')
            await get_camps(page,self.basic_info,True)
    
        aff=0
        #获取需要导出的报表的itemid
        j=1
        st_time,ed_time=calculate_timestamps2()
        rs_camp=self.ms.ExecQuery('select product_id,campaign_id from campaign where bid=? and is_on=1 and is_download_bb=0',(self.bid,))
        logging.info(f'{self.dpName},{self.bid},共有 {len(rs_camp)} 详情报表待下载')
        for cur_itemid,cur_campaign_id in rs_camp:
            save_bb_file_path=os.path.join(self.bb_save_path,f'{cur_itemid}.csv')

            if not os.path.exists(save_bb_file_path):
                purl=f'https://seller.shopee.co.id/portal/marketing/pas/product/manual/{cur_campaign_id}?group=last_three_month&from={st_time}&to={ed_time}'
                await repeat_goto(page,purl)
                sss=await self.check_login(page)
                if not sss:
                    await self.close_browser(browser)
                    return {'code':-2,'msg':'账户登录失败'}
                await wait_one_xpath(page,'//div[@class="campaign-title-left"]//div[@class="name"]',max_wait=200)
                await asyncio.sleep(5)
                el_btn_dcbb=await wait_one_xpath(page,'//button[@class="export-file-btn eds-button eds-button--normal"]')
                await el_btn_dcbb[0].click({'delay':200})
                doload_dir='C:/Users/Administrator/Downloads/'
                logging.info(f'{self.dpName},{self.bid},第 {j} 个itemid:{cur_itemid},开始下载报表')
                
                wait_count=0
                while True:
                    cur_probb_path=''
                    for cccpath in os.listdir(doload_dir):
                        cmat=re.match(r'Product-Ad-Data-{0}.*?\.csv$'.format(cur_campaign_id),cccpath)
                        if cmat:
                            logging.info(f'{self.dpName},{self.bid},成功下载报表:《{cccpath}》')
                            cur_probb_path=os.path.join(doload_dir,cccpath)
                            break
                    if cur_probb_path:
                        break
                    await asyncio.sleep(3)
                    if wait_count>60:
                        logging.info(f'{self.dpName},{self.bid},itemid:{cur_itemid},重新点击下载按钮')
                        await repeat_reload(page)
                        el_btn_dcbb=await wait_one_xpath(page,'//button[@class="export-file-btn eds-button eds-button--normal"]',max_wait=300)
                        await el_btn_dcbb[0].click({'delay':200})
                        wait_count=0
                    wait_count+=1
                
                logging.info(f'{self.dpName},{self.bid},itemid:{cur_itemid},开始上传报表详细信息')
                suc=dr_BBInfo(cur_probb_path,self.basic_info)
                aff+=suc
                #logging.info(f'{self.dpName},{self.bid},itemid:{cur_itemid},上传报表详细信息{suc}行')
                
                shutil.copy(cur_probb_path,save_bb_file_path)
                os.remove(cur_probb_path)
                aff_down=self.ms.ExecNoQuery('update campaign set is_download_bb=1 where campaign_id=? and product_id=?',(cur_campaign_id,cur_itemid))
                logging.info(f'{self.dpName},{self.bid},成功删除报表{cur_probb_path},标记下载状态:{aff_down}')
            else:
                aff_down=self.ms.ExecNoQuery('update campaign set is_download_bb=1 where campaign_id=? and product_id=?',(cur_campaign_id,cur_itemid))
                logging.info(f'{self.dpName},{self.bid},报表已经下载无需重复下载,标记下载状态:{aff_down}')
            
            logging.info(f'{self.dpName},{self.bid},itemid剩余:{len(rs_camp)-j}\n')
            j+=1
        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':'执行成功','aff':aff}

    async def yb_moni_delkw(self,campids=None):
        '''虾皮删除广告词'''
        browser=await openSunBrowser(self.basic_info,self.task_id)
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        page=await browser.newPage()
        url=f'https://seller.shopee.co.id/portal/marketing/pas/index'
        await repeat_goto(page,url)
        sss=await self.check_login(page)
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        await wait_one_xpath(page,'//div[@class="export-button"]')
        self.SPC_CDS,self.ck= await get_ck_and_spc_cds(page)
        logging.info(f'店铺:《{self.dpName}》,BrowserID:{self.bid},获取cookie成功,同时获取店铺SPC_CDS:{self.SPC_CDS}')
        campaign_dict0=await get_camps(page,self.basic_info)
        logging.info(f'店铺:《{self.dpName}》,BrowserID:{self.bid},共有 {len(campaign_dict0.keys())} 广告')
        if campids is None:
            campaign_dict=campaign_dict0
        else:
            campaign_dict={pid:camp_id for pid,camp_id in campids if campaign_dict0.get(pid)}

        logging.info(f'店铺:《{self.dpName}》,BrowserID:{self.bid},共有{len(campaign_dict.values())}个producdID需要广告优化...')
        
        res_suc=0
        pj=1
        #campaign_dict={'29061905212':'277411595'}
        for cur_itemid,cur_campaign_id in campaign_dict.items():

            logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},campaign_id:{cur_campaign_id},开始删除操作...')
            self.cpid=cur_itemid
            self.basic_info['pid']=cur_itemid
            sttt=get_three_time()
            st_time=sttt[0]
            ed_time=sttt[1]
            
            purl=f'https://seller.shopee.co.id/portal/marketing/pas/product/manual/{cur_campaign_id}?from={st_time}&to={ed_time}&group=last_three_month'

            await repeat_goto(page,purl)
            sss=await self.check_login(page)
            if not sss:
                await self.close_browser(browser)
                return {'code':-2,'msg':'账户登录失败'}
            await wait_one_xpath(page,'//div[@class="campaign-name"]',max_wait=60)
            await asyncio.sleep(3)
            
            st_time,ed_time=calculate_timestamps2()
            params={'SPC_CDS':self.SPC_CDS,'SPC_CDS_VER':2}
            kw_reports={}

            api_url='https://seller.shopee.co.id/api/pas/v1/product/manual/list_keyword_with_recommended_price/'
            post_data={"campaign_id":int(cur_campaign_id),"need_recommended_price":True,"header":{}}
            json_data= await make_request(page,api_url,params,post_data)
            if not json_data:
                await self.close_browser(browser)
                return {'code':-3,'msg':'获取广告词信息错误'}
            kw_kprs=json_data.get('data')
            if kw_kprs:
                krp_j=0
                for kw_kpr in kw_kprs:
                    if kw_kpr['keyword']['state']=='active':
                        cur_kw_info={}
                        curkw=kw_kpr['keyword']['keyword']
                        cur_kw_info['bid_price']=kw_kpr['keyword']['bid_price']/100000
                        cur_kw_info['match_type']=kw_kpr['keyword']['match_type']
                        cur_kw_info['state']=kw_kpr['keyword']['state']
                        kw_reports[curkw]=cur_kw_info
                        krp_j+=1
                logging.info(f'店铺:《{self.dpName}》,{self.bid},pid:{cur_itemid},获取广告词bid_price成功,共{len(kw_kprs)}个,其中active:{krp_j}个')
            else:
                logging.info(f'店铺:《{self.dpName}》,{self.bid},pid:{cur_itemid},广告词bid_price为空')

            api_url='https://seller.shopee.co.id/api/pas/v1/report/get/'
            post_data={"start_time":st_time,"end_time":ed_time,"campaign_type":"product",
                   "agg_type":"keyword","filter_params":{"campaign_id":int(cur_campaign_id)},"need_ratio":True,"header":{}}
            json_data= await make_request(page,api_url,params,post_data)
            if not json_data:
                await self.close_browser(browser)
                return {'code':-3,'msg':'获取广告词信息错误'}

            kw_zbs=json_data.get('data')
            if kw_zbs:
                zbs_j=0
                for kw_zb in kw_zbs:
                    curkw=kw_zb['key']
                    if kw_reports.get(curkw):
                        cur_kw_info=kw_reports[curkw]
                        cur_kw_info['CTR']=kw_zb['metrics']['ctr']
                        cur_kw_info['Clicks']=kw_zb['metrics']['click']
                        cur_kw_info['broad_gmv']=kw_zb['metrics']['broad_gmv']/100000
                        cur_kw_info['direct_gmv']=kw_zb['metrics']['direct_gmv']/100000
                        cur_kw_info['cost']=kw_zb['metrics']['cost']/100000
                        cur_kw_info['impression']=kw_zb['metrics']['impression']
                        kw_reports[curkw]=cur_kw_info
                        zbs_j+=1

                logging.info(f'店铺:《{self.dpName}》,{self.bid},pid:{cur_itemid},获取广告词报表参数成功,共{len(kw_zbs)}个,其中active:{zbs_j}个')
            else:
                logging.info(f'店铺:《{self.dpName}》,{self.bid},pid:{cur_itemid},广告词报表参数为空')


            cur_time=int(time.time())
            rs_ttt=self.ms.ExecQuery('select Search_Query,uploadTime from YN_AD_Info where Product_ID=?',(cur_itemid,))
            ttt_j=0
            for ccc_kw,upload_time in rs_ttt:
                ccc_kw=re.sub(r'[%.,/&+-]',' ',ccc_kw).strip().replace('  ',' ')
                if kw_reports.get(ccc_kw):
                    kw_reports[ccc_kw]['stay_time']=(cur_time-upload_time)/86400
                    ttt_j+=1

            logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},从数据库获取到 {len(rs_ttt)} 个词的时间,其中active:{ttt_j}个')

            kw_del=[]
            more_than_15=0
            kw_cansu_dict={}
            # with open(f'JSONDATA/kw_rp_{cur_itemid}.json','w',encoding='utf-8') as f:
            #     json.dump(kw_reports,f,ensure_ascii=False,indent=4)
            for rpkw,rpcs in kw_reports.items():
                if rpcs.get('CTR') is not None:
                    kw_gmv=rpcs['broad_gmv'] if rpcs['match_type']=='broad' else rpcs['direct_gmv']

                    if rpcs['CTR']<0.02 and rpcs['match_type']=='broad' and rpcs['Clicks']>=3 and kw_gmv==0:
                        kw_del.append(rpkw)
                        kw_cansu_dict[rpkw]=f"CTR:{rpcs['CTR']}<=0.02,Match Type:{rpcs['match_type']},clikcs:{rpcs['Clicks']}>=3,gmv:{kw_gmv}"
                    
                    elif rpcs['CTR']<0.05 and rpcs['match_type']=='exact' and rpcs['Clicks']>=6 and kw_gmv==0:
                        kw_del.append(rpkw)
                        kw_cansu_dict[rpkw]=f"CTR:{rpcs['CTR']}<=0.05,Match Type:{rpcs['match_type']},clikcs:{rpcs['Clicks']}>=6,gmv:{kw_gmv}"

                    elif rpcs['cost']>=30000 and kw_gmv==0 and rpcs['bid_price']==300:
                        kw_del.append(rpkw)
                        kw_cansu_dict[rpkw]=f"Expense:{rpcs['cost']}>=30000,gmv:{kw_gmv}=0,bid_price:{rpcs['bid_price']}=300"

                    elif rpcs['impression']>=100 and rpcs['Clicks']==0:
                        kw_del.append(rpkw)
                        kw_cansu_dict[rpkw]=f"impression:{rpcs['impression']}>=100,clikcs:{rpcs['Clicks']}=0"

                    elif rpcs['Clicks']==0 and rpcs.get('stay_time') and rpcs.get('stay_time')>=15:
                        more_than_15+=1
                        kw_del.append(rpkw)
                        kw_cansu_dict[rpkw]=f"clikcs:{rpcs['Clicks']}=0,创建时间:{rpcs['stay_time']:.2f}>=15"

                    elif rpcs['cost']>=100000 and kw_gmv==0 and rpcs['bid_price']>300:
                        kw_del.append(rpkw)
                        kw_cansu_dict[rpkw]=f"Expense:{rpcs['cost']}>=100000,gmv:{kw_gmv}=0,bid_price:{rpcs['bid_price']}>300"

            logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},有 {more_than_15} 个创建超过15天且0点击量')
            logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},活跃词共:{len(kw_reports.keys())}个')
            logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},需删除:{kw_del},共{len(kw_del)}个')

            if len(kw_del)==0:
                aff_del=self.ms.ExecNoQuery('update campaign set is_del_kw=1 where campaign_id=? and product_id=?',(cur_campaign_id,cur_itemid))
                logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},无需删除,标记删除状态:{aff_del}')
                pj+=1
                continue

            el_total_page=await wait_one_xpath(page,'//span[@class="eds-pager__total"]')
            await asyncio.sleep(5)
            await check_tc(page,'//div[@class="FULMadiY5u"]//div[text()="Maybe Later"]')
            total_page = await page.evaluate('(el) => el.textContent', el_total_page[0])
            total_page=int(total_page)
            logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},获取最大页数为:{total_page}')
            ppp=1
            while True:
                if len(kw_del)==0:
                    logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},删除列表已空')
                    break
                trs=await page.xpath('//div[@class="common-card card"]//div[@class="eds-table__fix-body eds-table__fix-left"]//table//tr')
                logging.info(f'店铺:《{self.dpName}》,{self.bid},第{ppp}页 共 {len(trs)} 个关键词')
                is_do_delete=False
                for tr in trs:

                    el_kwtxt= await tr.xpath('./td[2]//div[@class="ellipsis-content single"]')
                    if not el_kwtxt:
                        continue
                    hower_kw= await page.evaluate('(el) => el.textContent', el_kwtxt[0])
                    hower_kw=hower_kw.strip()
                    if hower_kw in kw_del:
                        logging.info(f'店铺:《{self.dpName}》,{self.bid},第 {ppp} 页,找到 :{hower_kw}')
                        el_deleted=await tr.xpath('./td[2]//span[@class="deleted"]')
                        if el_deleted:
                            logging.info(f'店铺:《{self.dpName}》,{self.bid},第 {ppp} 页,{hower_kw} 已被删除,无需操作')
                            kw_del.remove(hower_kw)
                        else:
                            while True:
                                await tr.hover()
                                el_del=await page.xpath(f'//div[@class="item-delete {hower_kw}"]')
                                if el_del:
                                    await el_del[0].click({'delay':200})
                                    el_qr_btn=await page.xpath('//div[@class="shopee-modal__footer"]//button[2]')
                                    if el_qr_btn:
                                        await el_qr_btn[0].click({'delay':200})
                                        await asyncio.sleep(3)
                                        is_do_delete=True
                                        del_time=datetime.datetime.now()
                                        zds_del=['BrowserID','DpName','GroupName','Product_ID','Search_Query','is_added','is_del','delTime','del_des']
                                        para_del=[self.bid,self.dpName,self.gname,cur_itemid,hower_kw,-2,1,del_time,kw_cansu_dict.get(hower_kw)]
                                        zd_on_del=['Product_ID','Search_Query']
                                        aff_ddd=self.ms.merge_into('yn_ad_csv',zds_del,para_del,zd_on_del)
                                        break
                                else:
                                    logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},campaign_id:{cur_campaign_id},可能只剩一个广告词,无法删除')
                                    break
                              
                            kw_del.remove(hower_kw)
                            res_suc+=1
                            logging.info(f'店铺:《{self.dpName}》,{self.bid},第 {ppp} 页,{hower_kw} 成功删除,剩余删除数:{len(kw_del)}')
                            upload_adkw_action(cur_itemid,cur_campaign_id,hower_kw,'delete',kw_cansu_dict.get(hower_kw),self.basic_info)
                            await asyncio.sleep(2)

                    if len(kw_del)==0:
                        break
                if len(kw_del)==0:
                    aff_del=self.ms.ExecNoQuery('update campaign set is_del_kw=1 where campaign_id=? and product_id=?',(cur_campaign_id,cur_itemid))
                    logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},campaign_id:{cur_campaign_id},全部删除完毕,标记删除状态:{aff_del}')
                    break
                
                if not is_do_delete:
                    el_next_btn=await page.xpath('//button[contains(@class,"eds-pager__button-next")]')
                    await el_next_btn[0].click({'delay':200})
                    await asyncio.sleep(5)
                    ppp+=1
                if ppp>total_page:
                    logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},广告词词抵达最后一页退出...')
                    break
            pj+=1

        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':'执行成功','aff':res_suc}
              
    async def yb_moni_editkw(self,campids=None):
        '''虾皮修改广告词'''
        browser=await openSunBrowser(self.basic_info,self.task_id)
        if not browser:
            
            return {'code':-1,'msg':'启动浏览器失败'}
        page=await browser.newPage()
        url=f'https://seller.shopee.co.id/portal/marketing/pas/index'
        await repeat_goto(page,url)
        sss=await self.check_login(page)
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        await wait_one_xpath(page,'//div[@class="export-button"]')
        self.SPC_CDS,self.ck= await get_ck_and_spc_cds(page)
        logging.info(f'店铺:《{self.dpName}》,BrowserID:{self.bid},获取cookie成功,同时获取店铺SPC_CDS:{self.SPC_CDS}')
        campaign_dict0=await get_camps(page,self.basic_info)
        logging.info(f'店铺:《{self.dpName}》,BrowserID:{self.bid},共有 {len(campaign_dict0.keys())} 广告')
        if campids is None:
            campaign_dict=campaign_dict0
        else:
            campaign_dict={pid:camp_id for pid,camp_id in campids if campaign_dict0.get(pid)}

        logging.info(f'店铺:《{self.dpName}》,BrowserID:{self.bid},共有{len(campaign_dict.values())}个producdID需要广告优化...')
        
        res_suc=0
        pj=1
        #campaign_dict={'26416254113':'294868536'}

        for cur_itemid,cur_campaign_id in campaign_dict.items():
            self.cpid=cur_itemid
            self.basic_info['pid']=cur_itemid            
            sttt=get_three_time()
            st_time=sttt[0]
            ed_time=sttt[1]
            logging.info(f'店铺:《{self.dpName}》,BrowserID:{self.bid},第{pj}个pid:{cur_itemid},campaign_id:{cur_campaign_id},开始修改操作...')
            purl=f'https://seller.shopee.co.id/portal/marketing/pas/product/manual/{cur_campaign_id}?from={st_time}&to={ed_time}&group=last_three_month'

            await repeat_goto(page,purl)
            sss=await self.check_login(page)
            if not sss:
                await self.close_browser(browser)
                return {'code':-2,'msg':'账户登录失败'}
            await wait_one_xpath(page,'//div[@class="campaign-name"]',max_wait=60)
            await asyncio.sleep(3)
            
            st_time,ed_time=calculate_timestamps2()
            params={'SPC_CDS':self.SPC_CDS,'SPC_CDS_VER':2}
            kw_reports={}

            api_url='https://seller.shopee.co.id/api/pas/v1/product/manual/list_keyword_with_recommended_price/'
            post_data={"campaign_id":int(cur_campaign_id),"need_recommended_price":True,"header":{}}
            json_data= await make_request(page,api_url,params,post_data)
            if not json_data:
                await self.close_browser(browser)
                return {'code':-3,'msg':'获取广告词信息错误'}
            kw_kprs=json_data.get('data')
            if kw_kprs:
                krp_j=0
                for kw_kpr in kw_kprs:
                    if kw_kpr['keyword']['state']=='active':
                        cur_kw_info={}
                        curkw=kw_kpr['keyword']['keyword']
                        cur_kw_info['bid_price']=kw_kpr['keyword']['bid_price']/100000
                        cur_kw_info['match_type']=kw_kpr['keyword']['match_type']
                        cur_kw_info['state']=kw_kpr['keyword']['state']
                        kw_reports[curkw]=cur_kw_info
                        krp_j+=1
                logging.info(f'店铺:《{self.dpName}》,{self.bid},pid:{cur_itemid},获取广告词bid_price成功,共{len(kw_kprs)}个,其中active:{krp_j}个')
            else:
                logging.info(f'店铺:《{self.dpName}》,{self.bid},pid:{cur_itemid},广告词bid_price为空')

            api_url='https://seller.shopee.co.id/api/pas/v1/report/get/'
            post_data={"start_time":st_time,"end_time":ed_time,"campaign_type":"product",
                   "agg_type":"keyword","filter_params":{"campaign_id":int(cur_campaign_id)},"need_ratio":True,"header":{}}
            json_data= await make_request(page,api_url,params,post_data)
            if not json_data:
                await self.close_browser(browser)
                return {'code':-3,'msg':'获取广告词信息错误'}

            kw_zbs=json_data.get('data')

            if kw_zbs:
                zbs_j=0
                for kw_zb in kw_zbs:
                    curkw=kw_zb['key']
                    if kw_reports.get(curkw):
                        cur_kw_info=kw_reports[curkw]
                        cur_kw_info['CTR']=kw_zb['metrics']['ctr']
                        cur_kw_info['Clicks']=kw_zb['metrics']['click']
                        cur_kw_info['broad_gmv']=kw_zb['metrics']['broad_gmv']/100000
                        cur_kw_info['direct_gmv']=kw_zb['metrics']['direct_gmv']/100000
                        cur_kw_info['cost']=kw_zb['metrics']['cost']/100000
                        cur_kw_info['impression']=kw_zb['metrics']['impression']
                        cur_kw_info['broad_order_amount']=kw_zb['metrics']['broad_order_amount']
                        cur_kw_info['direct_order_amount']=kw_zb['metrics']['direct_order_amount']
                        cur_kw_info['broad_cir']=kw_zb['metrics']['broad_cir']
                        cur_kw_info['direct_cir']=kw_zb['metrics']['direct_cir']
                        kw_reports[curkw]=cur_kw_info
                        zbs_j+=1

                logging.info(f'店铺:《{self.dpName}》,{self.bid},pid:{cur_itemid},获取广告词报表参数成功,共{len(kw_zbs)}个,其中active:{zbs_j}个')
            else:
                logging.info(f'店铺:《{self.dpName}》,{self.bid},pid:{cur_itemid},广告词报表参数为空')


            kws_edit={}
            ign_count=0

            for rpkw,rpcs in kw_reports.items():
                if rpcs.get('CTR') is not None:
                    kw_conversions=rpcs['broad_order_amount'] if rpcs['match_type']=='broad' else rpcs['direct_order_amount']
                    cur_acos=rpcs['broad_cir'] if rpcs['match_type']=='broad' else rpcs['direct_cir']
                    if kw_conversions>=1:
                        if cur_acos<0.3:
                            bid_price=300+kw_conversions*100
                            if bid_price>1000:
                                bid_price=1000
                            ad_type='Exact match'
                    
                        elif 0.3<=cur_acos<=0.5:
                            bid_price=300+kw_conversions*50
                            if bid_price>700:
                                bid_price=700
                            ad_type='Exact match'
                        else:
                            bid_price=200
                            ad_type='Exact match'
                        old_bid_price=int(rpcs['bid_price'])
                        old_ad_type='Exact match' if rpcs['match_type']=='exact' else 'Broad match'
                        if (bid_price,ad_type)==(old_bid_price,old_ad_type):
                            #print('忽略修改队列',cur_itemid,cur_kw,cur_kw_price_item)
                            ign_count+=1
                        else:
                            kws_edit[rpkw]=[bid_price,ad_type]


            el_total_page=await wait_one_xpath(page,'//span[@class="eds-pager__total"]')
            await wait_tc_xpath(page)
            total_page = await page.evaluate('(el) => el.textContent', el_total_page[0])
            total_page=int(total_page)

            logging.info(f'店铺:《{self.dpName}》,BrowserID:{self.bid},第{pj}个pid:{cur_itemid},需修改 {len(kws_edit.keys())} 个广告词,忽略修改:{ign_count},获取最大页数为:{total_page}')

            kws_edit_list=list(kws_edit.keys())
            for ppp in range(1,total_page+1):
                if len(kws_edit_list)==0:
                    break

                trs=await page.xpath('//div[@class="common-card card"]//div[@class="eds-table__fix-body eds-table__fix-left"]//table//tr')
                logging.info(f'第{pj}个pid,第{ppp}页,共加载{len(trs)} 个关键词')
                for tr in trs:
                    el_deleted=await tr.xpath('./td[2]//span[@class="deleted"]')
                    if el_deleted:
                        kws_edit_list=[]
                        break
                    
                    el_kwtxt= await tr.xpath('./td[2]//div[@class="ellipsis-content single"]')
                    if not el_kwtxt:
                        continue
                    hower_kw= await page.evaluate('(el) => el.textContent', el_kwtxt[0])
                    hower_kw=hower_kw.strip()
                    if hower_kw in kws_edit_list:
                        logging.info(f'第 {ppp} 页,找到 :{hower_kw}')
                        el_adtype=await tr.xpath('./td[3]//div[@class="eds-selector__inner line-clamp--1"]')
                        adtype_txt=await page.evaluate('(el) => el.textContent', el_adtype[0])
                        nadt=kws_edit[hower_kw][1]
                        if adtype_txt.lower()!=nadt.lower():
                            logging.info(f'《{hower_kw}》,更改广告类型至 {adtype_txt} => {nadt}')
                            await el_adtype[0].click({'delay':200})
                            await asyncio.sleep(1)
                            el_opt=await wait_one_xpath(page,f'//div[@class="eds-option"]//div[@class="item-title" and text()=" {nadt} " ]')
                            for qr_btn in el_opt:
                                try:
                                    await qr_btn.click({'delay':200})
                                    break
                                except Exception as e:
                                    pass
                            await asyncio.sleep(3)
                        else:
                            logging.info(f'《{hower_kw}》, {adtype_txt} => {nadt}无需修改广告类型')

                        el_bidp=await tr.xpath('./td[4]//span[@class="text"]')
                        bidp_txt=await page.evaluate('(el) => el.textContent', el_bidp[0])
                        oldp=int(bidp_txt.replace('Rp','').replace('.','').strip())
                        newp=kws_edit[hower_kw][0]
                        if oldp!=newp:
                            await el_bidp[0].click({'delay':200})
                            await asyncio.sleep(3)
                            el_iptbd=await page.xpath('//div[@class="bid-price-edit-popper"]//input[1]')
                            for jjj in range(1,len(el_iptbd)+1):
                                try:
                                    await el_iptbd[-jjj].click()  # 点击输入框
                                    await page.keyboard.down('Control')  # 按下 Ctrl 键（Mac 上使用 'Meta' 替代）
                                    await page.keyboard.press('A')  # 全选内容
                                    await page.keyboard.up('Control')  # 释放 Ctrl 键
                                    await page.keyboard.press('Backspace')  # 删除选中的内容
                                    await el_iptbd[-jjj].type(f'{newp}',{'delay':200})
                                    await asyncio.sleep(3)
                                    logging.info(f'《{hower_kw}》,修改价格 {oldp} => {newp}')
                                    break
                                except Exception as e:
                                    print(e)
                            
                        
                            el_qr_btn=await page.xpath('//div[@class="bid-price-edit-popper"]//span[text()=" Confirm "]')
                            for jjj in range(1,len(el_qr_btn)+1):
                                try:
                                    await el_qr_btn[-jjj].click({'delay':200})
                                    
                                    break
                                except Exception as e:
                                    print(e)
                            await asyncio.sleep(3)
                        else:
                            logging.info(f'《{hower_kw}》, {oldp} => {newp}无需修改价格')
                        logging.info(f'{hower_kw},{kws_edit[hower_kw]}修改操作完毕')

                        kws_edit_list.remove(hower_kw)
                        action_des=f'{json.dumps(kw_reports[hower_kw])},{adtype_txt} => {nadt},{oldp} => {newp}'
                        upload_adkw_action(cur_itemid,cur_campaign_id,hower_kw,'edit',action_des,self.basic_info)
                        # edit_time=datetime.datetime.now()
                        # zds_edit=['BrowserID','DpName','GroupName','Product_ID','Search_Query','is_edited','updateTime','edit_des']
                        # para_edit=[self.bid,self.dpName,self.gname,cur_itemid,hower_kw,1,edit_time,action_des]
                        # zd_on_edit=['Product_ID','Search_Query']
                        # aff_eee=self.ms.merge_into('yn_ad_csv',zds_edit,para_edit,zd_on_edit)
                        res_suc+=1

                    
                el_next_btn=await page.xpath('//button[contains(@class,"eds-pager__button-next")]')
                await el_next_btn[0].click({'delay':200})
                await asyncio.sleep(3)


            aff_edit=self.ms.ExecNoQuery('update campaign set is_edit_kw=1 where campaign_id=? and product_id=?',(cur_campaign_id,cur_itemid))
            logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},标记编辑状态:{aff_edit}')

            pj+=1
        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':'执行成功','aff':res_suc}
             
    async def yb_download_llbb2(self):
        '''下载产品流量报表'''
        browser = await openSunBrowser(self.basic_info,self.task_id)
        #browser=await openChrome()
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}

        page = await browser.newPage()
        page.on('dialog', lambda dialog: asyncio.ensure_future(dialog.dismiss()))  # 关闭弹窗

        aff = 0
        url = f'https://seller.shopee.co.id/datacenter/product/performance'
        await repeat_goto(page, url)
        sss = await self.check_login(page)
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        
        #await asyncio.sleep(3)
        await wait_one_xpath(page,'//span[text()="Export Data"]',max_wait=120)

        excel_content=await download_llbb(page,self.basic_info)
        if not excel_content:
            await page.close()
            await self.close_browser(browser)
            return {'code':-3,'msg':'下载报表超时失败'}
        
        logging.info(f'《{self.dpName}》,{self.bid},开始将流量报表上传至数据库...')   
        aff = dr_LLbb(excel_content,self.basic_info)
        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':'执行成功','aff':aff}

    async def yb_delete_noclick(self):
        '''删除虾皮无流量产品'''
        rs_need_del=self.ms.ExecQuery('select Item_ID from yn_llbb where browserid=? and [Product_Visitors_(Visit)]>0',(self.bid,))
        itemid_noll=[r[0] for r in rs_need_del]
        
        browser = await openSunBrowser(self.basic_info,self.task_id)
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}

        page=await browser.newPage()
        aff=0
        purl=f'https://seller.shopee.co.id/portal/product/list/all?page=1&size=48'
        await repeat_goto(page,purl)
        sss=await self.check_login(page)        
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        
        await asyncio.sleep(5)
        await wait_one_xpath(page,'//div[@class="tabs__tab"]')
        
        day_sss=10
        logging.info(f'《{self.dpName}》,{self.bid},正在获取超过{day_sss}天的产品,和最大页数...')
        max_p,pros_time_out=await js_get_xp_stay_pro(page,self.basic_info,day_sss)
        itemids_time_out=list(pros_time_out.keys())
        pat_itemid=re.compile(r'/portal/product/(\d+)')
        logging.info(f'《{self.dpName}》,{self.bid},成功获取超过{day_sss}天的产品:{len(itemids_time_out)} 个,最大页数:{max_p}')
        if len(itemids_time_out)==0:
            await page.close()
            await self.close_browser(browser)
            return {'code':0,'msg':'没有超过发布20天的产品','aff':0}

        all_del_count=0
        need_del_count=200
        is_tg=0 #判断是否需要跳过(如果最后两页都是0删除则跳过)
        for page_number in range(max_p,0,-1):
            itemids_need_change_state=[]
            self.page_number=page_number
            purl=f'https://seller.shopee.co.id/portal/product/list/all?page={page_number}&size=48'
            logging.info(f'《{self.dpName}》,{self.bid},正在删除第 {page_number} 页无流量数据,共{max_p}页')

            await repeat_goto(page,purl)
            sss=await self.check_login(page)
            if not sss:
                await self.close_browser(browser)
                return {'code':-2,'msg':'账户登录失败'}
            wait_pro=0
            while True:
                try:
                    el_pro_tits=await page.xpath('//div[@class="product-variation-item"]//span[@class="product-name-wrap"]')
                    if el_pro_tits:
                        break
                except Exception as e:
                    logging.error(f'《{self.dpName}》,{self.bid},第 {page_number} 页,加载列表错误 =>{e}')
                
                await asyncio.sleep(1)
                wait_pro+=1
                if wait_pro>120:
                    logging.error(f'《{self.dpName}》,{self.bid},第 {page_number} 页,加载列表超时,重新加载')
                    await repeat_goto(page,purl)
            await asyncio.sleep(3)
            el_tc=await page.xpath('//div[@class="eds-modal__content eds-modal__content--medium"]')
            if el_tc:
                logging.info(f'出现弹窗...')
                el_btn_close=await el_tc[0].xpath('.//button[1]')
                try:
                    await el_btn_close[0].click({'delay':200})
                except Exception as e:
                    logging.info(e)
            await check_tc(page,'//div[@class="FULMadiY5u"]//div[text()="Maybe Later"]')

            el_pros=await page.xpath('//div[@class="product-variation-item"]')
            ck_count=len(el_pros)
            el_ckpro=await wait_one_xpath(page,'//div[@class="eds-table__main-header"]/table[1]/thead[1]/tr[1]/th[1]//label[1]')
            await el_ckpro[0].click(options={'delay':200})
            
            all_del_count+=ck_count
            del_ind_list=[]
            del_ind=0
            for el_pro in el_pros:
                el_pro_url= await el_pro.xpath('.//div[@class="product-name-text"]//a[1]')
                if not el_pro_url:
                    continue
                href = await page.evaluate('(element) => element.href', el_pro_url[0])
                cur_itemid=pat_itemid.search(href).group(1)
                
                if (cur_itemid in itemid_noll) or (cur_itemid not in itemids_time_out):
                    
                    el_ck=await el_pro.xpath('./../../../../td[1]//label[@class="eds-checkbox"]')
                    await el_ck[0].click({'delay':200})
                    await asyncio.sleep(1)
                    if cur_itemid in itemid_noll:
                        itemid_noll.remove(cur_itemid)
                        logging.info(f'《{self.dpName}》,{self.bid},第 {page_number} 页,找到:{cur_itemid},有流量取消删除')
                    elif cur_itemid not in itemids_time_out:
                        logging.info(f'《{self.dpName}》,{self.bid},第 {page_number} 页,找到:{cur_itemid},发布未超{day_sss}天取消删除')
                    ck_count-=1
                    all_del_count-=1
                    del_ind_list.append(del_ind)
                else:
                    itemids_need_change_state.append(pros_time_out[cur_itemid])
                del_ind+=1
            
            if len(itemids_need_change_state)==0:
                is_tg+=1
            if is_tg>=2:
                logging.info(f'《{self.dpName}》,{self.bid},总删除量:{all_del_count},两页0删除,退出任务')
                await self.close_browser(browser)
                return {'code':0,'msg':'执行成功','aff':0}


            if all_del_count>need_del_count:
                logging.info(f'《{self.dpName}》,{self.bid},总删除量:{all_del_count},开始控制到{need_del_count}')
                el_pros=await page.xpath('//div[@class="product-variation-item"]')
                for jjj in range(len(el_pros)):
                    el_pro=el_pros[jjj]
                    el_pro_url= await el_pro.xpath('.//div[@class="product-name-text"]//a[1]')
                    href = await page.evaluate('(element) => element.href', el_pro_url[0])
                    cur_itemid=pat_itemid.search(href).group(1)
                    if jjj not in del_ind_list:
                        el_ck=await el_pro.xpath('./../../../../td[1]//label[@class="eds-checkbox"]')
                        await el_ck[0].click({'delay':200})
                        await asyncio.sleep(1)
                        itemids_need_change_state.remove(pros_time_out[cur_itemid])
                        all_del_count-=1
                        ck_count-=1
                        logging.info(f'《{self.dpName}》,{self.bid},{cur_itemid},取消勾选,总删除数剩余:{all_del_count},需恢复状态总数剩余:{len(itemids_need_change_state)}')
                        if all_del_count==need_del_count:
                            break

            logging.info(f'《{self.dpName}》,{self.bid},第 {page_number} 页,共勾选 {ck_count} 个产品,总删除数达:{all_del_count},剩余有流量需排除:{len(itemid_noll)}')

            if ck_count>0:
                el_elist_btn=await page.xpath('//span[text()="Delete"]')
                try:
                    await el_elist_btn[0].click({'delay':200})
                except Exception as e:
                    logging.info(e)

                await asyncio.sleep(5)

                el_div_pop_btns=await wait_one_xpath(page,'//div[@class="eds-modal"]//div[@class="eds-modal__footer-buttons"]')
                el_qr_btn=await el_div_pop_btns[0].xpath('./button[2]')
                await el_qr_btn[0].click({'delay':200})
                await asyncio.sleep(10)
                aff+=ck_count
            
            logging.info(f'《{self.dpName}》,{self.bid},第 {page_number} 页,成功删除 {ck_count} 个无流量产品')
            
            if len(itemids_need_change_state)>0:
                Thread(target=recover_podpro_daochu,args=(self.basic_info,itemids_need_change_state)).start()
            
            if all_del_count==need_del_count:
                logging.info(f'《{self.dpName}》,{self.bid},总删除数达到{all_del_count},退出删除')
                break

        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':'执行成功','aff':aff}
    
    async def yb_publish_draft_product(self):
        '''虾皮上架草稿箱'''
        browser=await openSunBrowser(self.basic_info,self.task_id)
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        
        page=await browser.newPage()
        #await stealth(page)
        aff=0
        purl='https://seller.shopee.co.id/portal/product/list/unpublished/draft'
        await repeat_goto(page,purl)
        
        sss=await self.check_login(page)
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        await asyncio.sleep(10)
        await wait_one_xpath(page,'//div[@class="tabs__tab"]')
        cot=await page.content()

        livetxt=etree.HTML(cot).xpath('//div[@class="list-header-title"]/text()')[0]
        allpro_count=int(livetxt.replace('products','').replace('product','').replace('.','').strip())
        logging.info(f'{self.dpName},{self.bid},草稿箱,还剩{allpro_count}个产品未上架')

        # await js_publish_xp_darft_pro(page,self.basic_info)
        # await asyncio.sleep(10000)
        
        max_ppp=math.ceil(allpro_count/20)
        for ppp in range(max_ppp,0,-1):
            logging.info(f'{self.dpName},{self.bid},草稿箱,正在上架第 {ppp} 页,共{max_ppp}页')

            purl=f'https://seller.shopee.co.id/portal/product/list/unpublished/draft?page={ppp}&size=20'
            await repeat_goto(page,purl)
            sss=await self.check_login(page)
            if not sss:
                await self.close_browser(browser)
                return {'code':-2,'msg':'账户登录失败'}
            await asyncio.sleep(5)

            await wait_one_xpath(page,'//div[@class="tabs__tab"]')
            el_tc=await page.xpath('//div[@class="eds-modal__content eds-modal__content--medium"]')
            if el_tc:
                logging.info(f'出现弹窗...')
                el_btn_close=await el_tc[0].xpath('.//button[1]')
                try:
                    await el_btn_close[0].click(random_delay())
                except Exception as e:
                    logging.info(e)
            await check_tc(page,'//div[@class="FULMadiY5u"]//div[text()="Maybe Later"]')

            el_ckpro=await wait_one_xpath(page,'//div[@class="eds-table__main-header"]/table[1]/thead[1]/tr[1]/th[1]//label[1]')
            await el_ckpro[0].click(random_delay())
            await asyncio.sleep(5)

            el_publish_btn=await page.xpath('//button[@class="eds-button eds-button--primary eds-button--normal"]//span[text()=" Publish "]')
            if el_publish_btn:
                try:
                    await el_publish_btn[0].click(random_delay())
                    await asyncio.sleep(5)
                except Exception as e:
                    logging.info(e)
            else:
                logging.error(f'{self.dpName},{self.bid},草稿箱上架第{ppp}页 按钮无法点击')
            aff+=20

        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':'执行成功','aff':aff}

    def get_pod_pro(self,count):
        
        basic_info=self.basic_info
        dir_path=basic_info['dir']
        bid=basic_info['BrowserID']
        dpName=basic_info['DpName']
        titlename='yntitle'
        datatype=2
        pod_price=basic_info['PODPrice']
        fac_name=basic_info['facName']
        rs_skus=self.ms.ExecQuery('select sku1,sku2 from YNPodFacSku where fac_name=?',(fac_name,))
        smtys={
            '标题':f'{titlename}Rcode',
            '产品ID':'itemid',
            '详细参数':'attributes',
            'SKU图片网址':'skuImg',
            '价格':'skuPirce',
            'SKUID':'skuid',
            '描述':'pdec'
        }

        zjys={
            'Option for Variation 1':'sku1',
            'Option for Variation 2':'sku2',
        }
        skus=[]
        for r_sku1,r_sku2 in rs_skus:
            skus.append([r_sku1[:18],r_sku2[:18]])


        sql_str_mb=f'''select mb1.did,mb1.dfile,
                    (SELECT COUNT(itemid) from ProShopeePh as p where p.pmbid=mb1.did and p.{titlename} is not null and p.ispodcp=1
                    and p.daochu>=0 and not exists(select 1 from YNPodPrice AS au WHERE au.ph_itemid = p.itemid AND au.daochu!=0 AND 
                    au.price ={pod_price}) 
                    ) as yndccount
                    from mb as mb1 
                    where duid=4 
                    and dstate=2 
                    and dxs=1
                    and mb1.dtype={datatype}
                    and mb1.did!=10768
                    order by yndccount desc'''
        
        
        rs_mb=self.ms.ExecQuery(sql_str_mb)
        need_pcount=count+100
        logging.info(f'店铺:《{dpName}》,bid:{bid},POD产品,价位{pod_price},有 {len(rs_mb)} 个模版可导出数据')
        dc_count=0
        excel_datas=[]
        file_j=1
        for mbid,mbpath,yndccount in rs_mb:

            dc_pros=[]
            cur_need=count-dc_count
            if yndccount==0:
                logging.info(f'店铺:《{dpName}》,bid:{bid},POD产品,价位{pod_price},模版:{mbid},无产品可导出跳过')
                continue

            sql_str_pro=f'''select top {need_pcount} * from proshopeeph as p
                                where pmbid=? 
                                and {titlename} is not null 
                                and p.daochu>=0 and p.ispodcp=1
                                and not exists(select 1 from YNPodPrice AS au WHERE au.ph_itemid = p.itemid AND au.daochu!=0 AND 
                                au.price ={pod_price})'''
            
            rs_pro=self.ms.ExecQuerydict(sql_str_pro,(mbid,))

            
            for r in rs_pro:
                tit= r[titlename]
                cur_itemid=r['itemid']
                kw_jiaoji=contains_word(tit,self.qqkws)
                if kw_jiaoji:
                    aff1=tms.ExecNoQuery(f'update qqc set usecount=usecount+1 where qtype=? and qcontent=?',('印尼语POD',kw_jiaoji[0]))
                    aff2=tms.ExecNoQuery('update proshopeeph set daochu=-5 where itemid=?',(cur_itemid,))
                    logging.info(f'itemd:{cur_itemid},出现侵权词:{kw_jiaoji},标记侵权:{aff1},拉黑数据:{aff2}')
                else:
                    if not r['pdec']:
                        r['pdec'] = r['yntitle']
                    if r['pdec'] and len(r['pdec']) > 2500:
                        r['pdec'] = r['pdec'][:2500]
                    r['price']=pod_price
                    r['skuPirce']=pod_price
                    dc_pros.append(r)
                    dc_count+=1


            rys=self.ms.ExecQuery('select * from lb where ldid=? order by lrow',(mbid,))
            dc_pros= dc_pros[:cur_need]
            eve_count=100
            #生成文件,每份最多100个产品
            
            for j in range(math.ceil(len(dc_pros)/eve_count)):

                pskudatas=[]
                start_ind=j*eve_count 
                end_ind=start_ind+eve_count
                cur_pros=dc_pros[start_ind:end_ind]
                cur_itemids=[]
                for item in cur_pros:
                    cur_itemids.append(item['itemid'])
                    for sku1,sku2 in skus:
                        new_pro=copy.copy(item)
                        characters = string.ascii_uppercase + string.digits
                        sku_id = ''.join(random.choices(characters, k=10))
                        new_pro['skuid']=sku_id
                        new_pro['sku1']=sku1
                        new_pro['sku2']=sku2
                        pskudatas.append(new_pro)
                
                wb=openpyxl.load_workbook(mbpath)
                ws=wb['Template']
                row=7
                for pro in pskudatas:
                    if not pro['pdec']:
                        pro['pdec']=pro['yntitle']
                    if pro['pdec'] and len(pro['pdec'].strip())<20:
                        pro['pdec']=pro['yntitle']

                    allimgs=[pro['image']]
                    if pro['images']:
                        try:
                            allimgs.extend(json.loads(pro['images']))
                        except Exception as e:
                            pass
                    #allimgs=list(set(allimgs))
                    rol=1
                    try:
                        for ry in rys:
                            mbcol=ry[1]
                            smtcol=ry[2]
                            gd=ry[4]

                            if smtcol=='SKU图片网址':
                                rol+=1
                                continue
                            
                            if '无' not in smtcol and smtcol:
                                if smtcol=='SKU名称':
                                    if zjys.get(mbcol):
                                        ws.cell(row=row,column=rol).value=pro[zjys.get(mbcol)]
                                        if zjys.get(mbcol)=='sku1' and not pro['sku1']:
                                            ws.cell(row=row,column=rol).value='style'

                                elif smtcol=='主图网址':
                                    if len(allimgs)>0:
                                        ws.cell(row=row,column=rol).value=allimgs.pop(0)

                                else:
                                    ws.cell(row=row,column=rol).value=str(pro[smtys.get(smtcol)])
                            
                            else:
                                ws.cell(row=row,column=rol).value=gd
                                if gd=='size' and not pro['sku2']:
                                    ws.cell(row=row,column=rol).value=''

                            rol+=1
                        row+=1
                    except Exception as e:
                        logging.info(f'第{row}行,第{rol}列填写错误 =>{e}')

                file_path=f'{dir_path}/{self.bid}-{file_j:02d}_{mbid}-{j+1}-{len(cur_pros)}-{int(time.time())}.xlsx'
                wb.save(file_path)
                file_j+=1
                excel_datas.append({
                    'file_path':file_path,
                    'dc_itemids':cur_itemids,
                    'pod_price':pod_price,
                    'mbid':mbid,
                    'fac_name':fac_name
                })
                print(f'店铺:《{dpName}》,bid:{bid},mb:{mbid},第{j+1}份文件,导出 {len(cur_pros)} 个产品,成功保存至:《{file_path}》')
                if len(excel_datas)>=4:
                    break
            if dc_count>=count:
                logging.info(f'店铺:《{dpName}》,bid:{bid},当前提取数据:{dc_count},达到所需数量:{count},退出导出')
                break
            if len(excel_datas)>=4:
                logging.info(f'店铺:《{dpName}》,bid:{bid},当前提取数据:{dc_count},达到文件上限4份,退出导出')
                break
        return excel_datas

    async def yb_publish_podpro(self):
        '''虾皮POD自动发布产品'''

        browser=await openSunBrowser(self.basic_info,self.task_id)
        #browser =await openChrome()
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        page=await browser.newPage()
        aff=0

        purl='https://seller.shopee.co.id/portal/product-mass/import/upload'
        await repeat_goto(page,purl)
        
        sss=await self.check_login(page)
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        
        need_dc_count= await get_POD_count(page,self.basic_info)
        if need_dc_count<=0:
            await self.close_browser(browser)
            return {'code':0,'msg':'产品上传达到上限','aff':0}
        logging.info(f'开始获取印尼POD侵权词...')
        rs_qqc=self.ms.ExecQuery('select qcontent from qqc where qtype=?',('印尼语POD',))
        self.qqkws=[r[0] for r in rs_qqc]
        logging.info(f'共获取 {len(self.qqkws)} 个印尼POD侵权词')

    
        excel_datas=self.get_pod_pro(need_dc_count)
        logging.info(f'店铺:《{self.dpName}》,{self.bid},共生成 {len(excel_datas)} 个文件,开始循环上传')
        no_mbid=[]
        suc=0
        file_names=[]
        ydc_itemids_dict={}
        for j in range(len(excel_datas)):
            if j>=4:
                break
            dc_itemids=excel_datas[j]['dc_itemids']
            file_path=excel_datas[j]['file_path']
            pod_price=excel_datas[j]['pod_price']
            fac_name=excel_datas[j]['fac_name']
            mbid=excel_datas[j]['mbid']
            if mbid in no_mbid:
                logging.info(f'店铺:《{self.dpName}》,{self.bid},开始上传第 {j+1} 个文件,模版 {mbid} 需要更新,跳过')
                continue
            logging.info(f'店铺:《{self.dpName}》,{self.bid},开始上传第 {j+1} 个文件:《{file_path}》')

            upload_ipt=await wait_one_xpath(page,'//input[@class="eds-file-uploader uploader eds-upload__input"]',max_wait=120)
            await upload_ipt[0].uploadFile(file_path)
            file_name=os.path.basename(file_path)
            file_names.append(file_name)
            ydc_itemids_dict[file_name]=dc_itemids
            await asyncio.sleep(5)

        res_reports=await get_xp_report(page,file_names,self.basic_info)
        for fff_nnn,res_report in res_reports.items():
            logging.info(f'店铺:《{self.dpName}》,{self.bid},文件 《{fff_nnn}》上传结束')
            rp_state='Successful'
            file_id=res_report['id']
            rp_status=res_report['record_status']
            suc_count=res_report['success_count']
            all_count=res_report['total_count']
            handled_count=res_report['handled_count']
            fail_count=all_count-suc_count
            ctime=timestamp_to_sql_datetime(res_report['ctime'])
            mtime=res_report['mtime']
            if mtime!=0:
                mtime=timestamp_to_sql_datetime(res_report['ctime'])
            else:
                mtime=None

            shopid=res_report['shop_id']
            
            if suc_count==0:
                rp_state='Unsuccessful'

            if rp_status==7 or handled_count==0:
                no_mbid.append(mbid)
                rp_state='Failed'
            
            if rp_state!='Successful':

                zds=['FileID','mbid','shopID','[all]','[suc]','[fail]','status','state','downloadPath',
                     'bid','bname','gname','create_time','mass_time']
                paras=[file_id,mbid,shopid,all_count,suc_count,fail_count,rp_state,rp_status,file_path,
                       self.bid,self.dpName,self.gname,ctime,mtime]
                aff=self.ms.merge_into('ShopeeReport',zds,paras,['FileID'],True)
                logging.info(f'店铺:《{self.dpName}》,{self.bid},文件 《{fff_nnn}》上传失败,登记错误报告:{aff}')
            else:
                aff=0
                now_time=datetime.datetime.now()
                cur_dc_itemids=ydc_itemids_dict[fff_nnn]
                for phitemid in cur_dc_itemids:
                    zds=['upload_time','price','ph_itemid','daochu','fac_name']
                    paras=[now_time,pod_price,phitemid,2,fac_name]
                    aff+=self.ms.merge_into('YNPodPrice',zds,paras,['price','ph_itemid'])
                suc+=1
                logging.info(f'店铺:《{self.dpName}》,{self.bid},文件 《{fff_nnn}》上传成功,标记导出状态:{aff}')
                await asyncio.sleep(1)
            

        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':'执行成功','aff':suc}

    async def yb_cj_list_count(self):
        '''虾皮采集我的产品概况'''
        self.list_info={'isloaded':0}
        async def intercept_response(res):
            
            if "seller.shopee.co.id/api/v3/mpsku/list/get_product_count_limit" in res.request.url:
                try:
                    json_data=await res.json()
                    self.list_info['listing_limit']=json_data['data']['publish_limit']
                    self.list_info['isloaded']+=1
                except Exception as e:
                    logging.info(f'{self.dpName},{self.bid},解析接口《v3/mpsku/list/get_product_count_limit》数据错误 => {e}')
            
            if "seller.shopee.co.id/api/v3/mpsku/list/v2/get_list_count" in res.request.url:

                try:
                    json_data=await res.json()
                    count_infos=json_data['data']['count_infos']
                    count_info_dict={count_info['list_type']:count_info['count'] for count_info in count_infos}
                    self.list_info['live']=count_info_dict.get('live_all')
                    self.list_info['banned']=count_info_dict.get('banned')
                    self.list_info['deboosted']=count_info_dict.get('deboosted')
                    self.list_info['shopee_deleted']=count_info_dict.get('deleted')
                    self.list_info['under_shopee_review']=count_info_dict.get('reviewing')
                    self.list_info['delisted']=count_info_dict.get('delisted')
                    self.list_info['draft']=count_info_dict.get('draft')
                    self.list_info['isloaded']+=1
                except Exception as e:
                    logging.info(f'{self.dpName},{self.bid},解析接口《v3/mpsku/list/v2/get_list_count》数据错误 => {e}')

        
        browser = await openSunBrowser(self.basic_info,self.task_id)
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        page=await browser.newPage()
        page.on('response', lambda rep: asyncio.ensure_future(intercept_response(rep)))
        aff=0
        purl=f'https://seller.shopee.co.id/portal/product/list/all'
        await repeat_goto(page,purl)
        sss=await self.check_login(page)        
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        
        wait_count=0
        self.shopid=await js_req_shopid(page,self.basic_info)
        while True:
            if self.list_info.get('isloaded')==2 and self.shopid:
                logging.info(f'{self.dpName},{self.bid},成功获取产品概况')
                break
            await asyncio.sleep(1)

            wait_count+=1
            if wait_count>=120:
                logging.info(f'{self.dpName},{self.bid},获取概况数据超时,退出...')
                await page.close()
                await self.close_browser(browser)
                return {'code':-3,'msg':'获取概况数据超时'}

        self.list_info.pop('isloaded')
        cur_time=datetime.datetime.now() 
        zds=['shopid','bid','BName','GroupName','userName','password','SJBM','YYBM','lg']
        params=[self.shopid,self.bid,self.dpName,self.gname,self.userName,self.password,self.sjbm,self.yybm,'YinNi']
        zds=zds+list(self.list_info.keys())
        params=params+list(self.list_info.values())
        rs=self.ms.ExecQuery('select count(*) from ShopeeListCount where shopid=?',(self.shopid,))
        if rs[0][0]==0:
            zds.append('upload_time')
            params.append(cur_time)
            zdstr=','.join(zds)
            wstr=','.join(['?' for _ in params])
            aff=self.ms.ExecNoQuery(f'insert into ShopeeListCount({zdstr}) values ({wstr})',params)
        else:
            zds.append('update_time')
            params.append(cur_time)
            params.append(self.shopid)
            zdstr=','.join([f'{zd}=?' for zd in zds])
            aff=self.ms.ExecNoQuery(f'update ShopeeListCount set {zdstr} where shopid=?',params)

        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':'采集成功','aff':aff}

    async def yb_cj_wgpro(self):
        '''采集违规产品'''
        self.list_info={'isloaded':False}

        async def intercept_response(res):


            if "seller.shopee.co.id/api/v3/mpsku/list/v2/get_list_count" in res.request.url:

                try:
                    json_data=await res.json()
                    count_infos=json_data['data']['count_infos']
                    count_info_dict={count_info['list_type']:count_info['count'] for count_info in count_infos}
                    self.list_info['shopee_deleted']=count_info_dict.get('deleted')
                    self.list_info['isloaded']=True
                except Exception as e:
                    logging.info(f'{self.dpName},{self.bid},解析接口《v3/mpsku/list/v2/get_list_count》数据错误 => {e}')

        violation_type_dict={
            4:'Counterfeit and IP Infringement'
        }

        browser = await openSunBrowser(self.basic_info,self.task_id)
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        page=await browser.newPage()
        page.on('response', lambda rep: asyncio.ensure_future(intercept_response(rep)))
        purl=f'https://seller.shopee.co.id/portal/product/list/violation/deleted'
        await repeat_goto(page,purl)
        sss=await self.check_login(page)        
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        wait_count=0
        await asyncio.sleep(3)
        self.shopid=await js_req_shopid(page,self.basic_info)
        while True:
            if self.list_info.get('isloaded') and self.shopid:
                logging.info(f'{self.dpName},{self.bid},成功获取产品概况')
                break
            await asyncio.sleep(1)

            wait_count+=1
            if wait_count>=120:
                logging.info(f'{self.dpName},{self.bid},获取概况数据超时,退出...')
                await page.close()
                await self.close_browser(browser)
                return {'code':-3,'msg':'获取概况数据超时'}
            
        wg_pro_count=self.list_info['shopee_deleted']
        if wg_pro_count==0:
            logging.info(f'{self.dpName},{self.bid},无违规产品')
            await page.close()
            await self.close_browser(browser)
            return {'code':0,'msg':'无违规产品','aff':0}
        
        logging.info(f'{self.dpName},{self.bid},有 {wg_pro_count} 个违规产品,开始获取违规内容...')

        api_url='https://seller.shopee.co.id/api/v3/mpsku/list/v2/get_banned_product_list'
        spdc,ck=await get_ck_and_spc_cds(page)
        wg_pros=[]
        for ppp in range(1,math.ceil(wg_pro_count/48)+1):
            params={'SPC_CDS': spdc,
                    'SPC_CDS_VER': 2,
                    'page_number': ppp,
                    'page_size': 48,
                    'list_type': 'deleted'
            }
            json_data=await make_request(page,api_url,params)
            # with open('wggg.json','w',encoding='utf-8') as f:
            #     json.dump(json_data,f,ensure_ascii=False,indent=4)
            try:
                pros=json_data['data']['products']
            except Exception as e:
                logging.error(f'{self.dpName},{self.bid},json_data获取data错误 => {e}')
            
            for pro in pros:
                pro_dict={}
                try:
                    pro_dict['itemid']=str(pro['id'])
                    pro_dict['PH_itemid']=str(pro['parent_sku'])
                    pro_dict['Product_name']=pro['name']
                    rcode=None 
                    rcode_mat=re.search(r'.*\|(.{8})\|$',pro['name'])
                    if rcode_mat:
                        rcode=rcode_mat.group(1)
                    pro_dict['rcode']=rcode
                    pro_dict['pic']=f"https://down-id.img.susercontent.com/file/{pro['cover_image']}"
                    pro_dict['create_time']=timestamp_to_sql_datetime(pro['create_time'])
                    pro_dict['modify_time']=timestamp_to_sql_datetime(pro['modify_time'])
                    pro_dict['Delete_time']=timestamp_to_sql_datetime(pro['banned_info']['banned_time'])
                    pro_dict['banned_reason']=int(pro['banned_info']['banned_reason'][0])
                    pro_dict['Violation_reason']=pro['banned_info']['reasons'][0]['description']
                    pro_dict['Suggestion']=pro['banned_info']['reasons'][0]['explanation']
                    wg_status=pro['status']
                    if violation_type_dict.get(wg_status):
                        pro_dict['Violation_type']=violation_type_dict.get(wg_status)
                    else:
                        pro_dict['Violation_type']=str(wg_status)
                    wg_pros.append(pro_dict)

                except Exception as e:
                    logging.error(f'{self.dpName},{self.bid},解析违规参数错误 => {e}')

        if not wg_pros:
            await page.close()
            await self.close_browser(browser)
            return {'code':-3,'msg':'获取违规产品失败'}
        logging.info(f'{self.dpName},{self.bid},成功获取 {len(wg_pros)} 个违规产品,开始更新到数据表《ShopeeDeletePro》')
        cur_time=datetime.datetime.now() 

        aff=0
        end_qq=0
        for wg_pro in wg_pros:
            zds=['shopid','bid','BName','GroupName','userName','password','SJBM','YYBM','lg']
            params=[self.shopid,self.bid,self.dpName,self.gname,self.userName,self.password,self.sjbm,self.yybm,'YinNi']
            cur_itemid=wg_pro['itemid']
            ph_itemid=wg_pro['PH_itemid']
            if ph_itemid:
                end_qq+=self.ms.ExecNoQuery('update proshopeeph set daochu=-6 where itemid=?',(ph_itemid,))
            zds=zds+list(wg_pro.keys())
            params=params+list(wg_pro.values())
            rs=self.ms.ExecQuery('select count(*) from ShopeeDeletePro where shopid=? and itemid=?',(self.shopid,cur_itemid))
            if rs[0][0]==0:
                zds.extend(['upload_time','update_time'])
                params.extend([cur_time,cur_time])
                zdstr=','.join(zds)
                wstr=','.join(['?' for _ in params])
                
                aff+=self.ms.ExecNoQuery(f'insert into ShopeeDeletePro({zdstr}) values ({wstr})',params)
            else:
                zds.append('update_time')
                params.append(cur_time)
                params.extend([self.shopid,cur_itemid])
                zdstr=','.join([f'{zd}=?' for zd in zds])
                aff+=self.ms.ExecNoQuery(f'update ShopeeDeletePro set {zdstr} where shopid=? and itemid=?',params)

        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':f'采集成功,拉黑原始数据:{end_qq}','aff':aff}

    async def yb_cj_add_cost(self):
        '''加购成本表补充广告费'''
        browser = await openSunBrowser(self.basic_info,self.task_id)
        #browser=await openChrome()
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        page=await browser.newPage()
        st_time,ed_time=calculate_timestamps2(30)

        url=f'https://seller.shopee.co.id/portal/marketing/pas/index?from={st_time}&to={ed_time}&type=new_cpc_homepage&group=last_month'
        await repeat_goto(page,url)
        sss=await self.check_login(page)
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        
        await wait_one_xpath(page,'//div[@class="export-button"]',max_wait=180)
        shopid=await js_req_shopid(page,self.basic_info)
        self.basic_info['shopid']=shopid
        campaign_infos=await get_all_camp_info(page,self.basic_info,dayjg=30)
        probb=await get_xp_probb(page,self.basic_info)
        probb_cart_dict={}

        for pro in probb:
            ccc_itemid=str(str(pro['id']))
            probb_cart_dict[ccc_itemid]={
                'add_to_cart_buyers':pro['add_to_cart_buyers'],
                'conversions':pro['confirmed_buyers'],
                'conversion_rate':pro['uv_to_add_to_cart_rate'],
                'cart_to_conversion_rate':round(pro['confirmed_buyers']/pro['add_to_cart_buyers'],4)
            }
        
        suc=0
        cur_timetstamp=int(time.time())
        pj=1

        for entry in campaign_infos:

            camid=str(entry['campaign']['campaign_id'])
            itemid=str(entry['manual_product_ads']['item_id'])
            all_cost=entry['report']['cost']/100000
            camp_broad_order=entry['report']['broad_order']
            start_timetstamp=entry['campaign']['start_time']
            pname=entry['title']
            create_days=int((cur_timetstamp-start_timetstamp)/86400)
            ad_url=f'https://seller.shopee.co.id/portal/marketing/pas/product/manual/{camid}?group=last_month'
            purl=f'https://shopee.co.id/product/{shopid}/{itemid}/'
            res_Xpcamp=await update_XPcamp(page,self.basic_info,entry)
            logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{itemid},更新《campaign》,状态:{res_Xpcamp}')
            try:
                
                pro_info=probb_cart_dict.get(itemid)
                avg_cost=None
                cost_per_conversion=None


                if pro_info is not None:
                    add_cart_count=pro_info['add_to_cart_buyers']
                    conversions=pro_info['conversions']
                    conversion_rate=pro_info['conversion_rate']
                    cart_to_conversion_rate=pro_info['cart_to_conversion_rate']
                    if conversions>0:
                        cost_per_conversion=round(all_cost/conversions,2)
                    avg_cost=round(all_cost/add_cart_count,2)
                    all_cost=round(all_cost,2)

                    zds=['product_id','campaign_id','purl','ad_url','shopid','cost_30day','add_cart_30day','avg_cost',
                        'bid','BName','GroupName','userName','password','SJBM','YYBM','create_days','Product_Name_Ad_Name',
                        'conversions','camp_broad_order','conversion_rate','cart_to_conversion_rate','cost_per_conversion'
                        ]
                    params=[itemid,camid,purl,ad_url,shopid,all_cost,add_cart_count,avg_cost,
                            self.bid,self.dpName,self.gname,self.userName,self.password,self.sjbm,self.yybm,create_days,pname,
                            conversions,camp_broad_order,conversion_rate,cart_to_conversion_rate,cost_per_conversion
                            ]
                    zds_on=['product_id']
                    aff=self.ms.merge_into('ShopeeADCost',zds,params,zds_on,True)
                    
                    logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{itemid},获取30天广告总消费:{all_cost},获取30天加购总人数:{add_cart_count}')
                else:
                    zds=['product_id','campaign_id','purl','ad_url','shopid','cost_30day','add_cart_30day',
                        'bid','BName','GroupName','userName','password','SJBM','YYBM','create_days','Product_Name_Ad_Name',
                        'conversions','camp_broad_order','conversion_rate','cart_to_conversion_rate','cost_per_conversion'
                        ]
                    params=[itemid,camid,purl,ad_url,shopid,all_cost,0,
                            self.bid,self.dpName,self.gname,self.userName,self.password,self.sjbm,self.yybm,create_days,pname,
                            0,camp_broad_order,None,None,cost_per_conversion
                            ]
                    zds_on=['product_id']
                    aff=self.ms.merge_into('ShopeeADCost',zds,params,zds_on,True)
                    logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{itemid},获取30天广告总消费:{all_cost},获取30天加购总人数失败')

                suc+=aff 
                logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{itemid},30天平均广告成本:{avg_cost},更新状态:{aff}')
                
            except Exception as e:
                traceback.print_exc()
                logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid,出错 => {e}')
            pj+=1

        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':f'采集加购成本成功','aff':suc}

    async def yb_pause_ad(self):
        '''测品广告管理'''
        browser = await openSunBrowser(self.basic_info,self.task_id)
        #browser=await openChrome()
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        page=await browser.newPage()
        st_time,ed_time=calculate_timestamps2(90)
        url=f'https://seller.shopee.co.id/portal/marketing/pas/index?from={st_time}&to={ed_time}&type=new_cpc_homepage&group=last_month'
        await repeat_goto(page,url)
        sss=await self.check_login(page)
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        
        sql_str=f'''select product_id,campaign_id from ShopeeADCost 
                where bid='{self.bid}'
                and create_days>3
                and (
                (cost_30day>=20000 and add_cart_30day=0) 
                or 
                (cost_30day between 30000 and 150000 and avg_cost>6000 and conversions=0)
                or
                (conversion_rate<0.07 and add_cart_30day>=5 and conversions=0)
                or
                (cart_to_conversion_rate<0.07 and add_cart_30day>=30 and conversions=0)
                )
            '''
        rs_shadcost=self.ms.ExecQuery(sql_str)
        ccc_pids=[r[0] for r in rs_shadcost]
        
        await wait_one_xpath(page,'//div[@class="export-button"]',max_wait=180)
        all_need_pause,all_camp_ids=await get_need_pause_ad(page,self.basic_info,ccc_pids)
        
        logging.info(f'店铺:《{self.dpName}》,{self.bid},共{len(all_camp_ids)} 广告,需暂停 {len(all_need_pause)} 个')
        if not all_need_pause:
            await page.close()
            await self.close_browser(browser)
            return {'code':0,'msg':'无需暂停任何广告','aff':0}
        
        res=await pause_ad(page,self.basic_info,[int(campid) for campid in all_need_pause]) 
        code=res['code']
        if code==0:
            logging.info(f'店铺:《{self.dpName}》,{self.bid},成功暂停 {len(all_need_pause)} 个广告')
        else:
            logging.info(f'店铺:《{self.dpName}》,{self.bid},暂停失败')
        await page.close()
        await self.close_browser(browser)
        return res

    def is_has_com_pro(self,dcytpe,shopid):
        
        if dcytpe==1:
            return True

        if dcytpe==2:
            sql_ccc=f'''SELECT count(distinct itemid) from proshopeeph where  search_clicks>0  and daochu>=0
                        and dc_shopids not like '%{shopid}%' '''
        elif dcytpe==3:
            sql_ccc=f'''SELECT count(distinct itemid) from proshopeeph where  my_sold between 1 and 2  and daochu>=0
                        and dc_shopids not like '%{shopid}%' '''
        rs=self.ms.ExecQuery(sql_ccc)

        if rs[0][0]==0:
            logging.info(f'店铺:《{self.dpName}》,{self.bid},可导出数据为0')
            return False
        else:
            return True
               
    def get_com_pro(self,count):
        
        basic_info=self.basic_info
        dir_path=basic_info['dir']
        bid=basic_info['BrowserID']
        dc_type=basic_info['common_dc_type']
        dpName=basic_info['DpName']
        titlename='yntitle'
        ordername='shopee_id_order'
        biid=self.basic_info['id']
        shopid=self.basic_info['shopid']
        datatype=1
        smtys={
            '标题':f'{titlename}Rcode',
            '产品ID':'itemid',
            '详细参数':'attributes',
            'SKU图片网址':'skuImg',
            '价格':'skuPirce',
            'SKUID':'skuid',
            '描述':'pdec'
        }

        zjys={
            'Option for Variation 1':'sku1',
            'Option for Variation 2':'sku2',
        }

        where_str=f'{ordername}=0 and price between 800 and 6000'
        if dc_type!=1:
            where_str='search_clicks>0' if dc_type==2 else 'my_sold between 1 and 2'
        px_dict={
            1:'可导出数据',
            2:'有流量数据',
            3:'出单数据'
        }
        px=px_dict[dc_type]
        sql_str_mb=f'''                
                    select mb1.did,mb1.dfile,
                    (SELECT COUNT(DISTINCT itemid) from ProShopeePh where pmbid=mb1.did and {titlename} is not null 
                    and daochu=0 and {where_str}) as yndccount
                    from mb as mb1 
                    where duid=4 
                    and dstate=2 
                    and dxs=1
                    and mb1.dtype={datatype}
                    order by yndccount desc
                '''
        
        
        rs_mb=self.ms.ExecQuery(sql_str_mb)
        need_pcount=count+100
        logging.info(f'店铺:《{dpName}》,{bid},按 {px} 排序,有 {len(rs_mb)} 个模版可导出数据')
        dc_count=0
        excel_datas=[]
        file_j=1
        for mbid,mbpath,yndccount in rs_mb:

            cur_need=count-dc_count
            if yndccount==0:
                logging.info(f'店铺:《{dpName}》,{bid},POD产品,按 {px} 排序,模版:{mbid},无产品可导出跳过')
                continue
            
            
            if dc_type==1:
                sql_str_pro=f'''
                            WITH cte AS (
                                SELECT DISTINCT TOP {need_pcount} itemid 
                                FROM proshopeeph WITH (ROWLOCK, UPDLOCK, READPAST) 
                                WHERE pmbid=? 
                                AND {ordername} = 0  
                                AND {titlename} IS NOT NULL 
                                AND daochu = 0
                            )
                            UPDATE proshopeeph
                            SET daochu = {biid}
                            OUTPUT inserted.*
                            WHERE itemid IN (SELECT itemid FROM cte)
                            '''
            elif dc_type==2:
 
                sql_str_pro=f'''
                                SELECT * from proshopeeph 
                                where pmbid=? and {titlename} is not null and daochu>=0 and search_clicks>0
                                and dc_shopids not like '%{shopid}%'

                                
                        '''
            elif dc_type==3:
                sql_str_pro=f'''
                            select * from proshopeeph 
                            where pmbid=? and {titlename} is not null and daochu>=0 and my_sold between 1 and 2
                            and dc_shopids not like '%{shopid}%'
                        '''
            
            rp=self.ms.ExecQuerydict(sql_str_pro,(mbid,))
            new_rp=[]
            yjc_itemid={}
            for r in rp:
                itemid=r['itemid']
                yntile=r['yntitle']
                if yjc_itemid.get(itemid):
                    if yjc_itemid[itemid]=='不侵权':
                        new_rp.append(r)
                else:
                    jiaojikws=contains_word(yntile,self.qqkws)
                    if jiaojikws:
                        aff1=tms.ExecNoQuery(f'update qqc set usecount=usecount+1 where qtype=? and qcontent=?',('印尼语普货',jiaojikws[0]))
                        aff2=self.ms.ExecNoQuery('update proshopeeph set daochu=-5 where itemid=?',(itemid,))
                        logging.info(f'《proshopeeph》,itemid:{itemid},触发侵权词{jiaojikws}:{aff1},加入黑名单:{aff2}')
                        yjc_itemid[itemid]='侵权'
                    else:
         
                        new_rp.append(r)
                        yjc_itemid[itemid]='不侵权'
            

            rys=self.ms.ExecQuery('select * from lb where ldid=? order by lrow',(mbid,))
            pros_list=getsmtpro(new_rp)
            pros_list=pros_list[:cur_need]
            dc_count+=len(pros_list)
            eve_count=100
            #生成文件,每份最多100个产品
            phl=420
            pbs=1
            for j in range(math.ceil(len(pros_list)/eve_count)):

                start_ind=j*eve_count 
                end_ind=start_ind+eve_count
                cur_pros=pros_list[start_ind:end_ind]
                cur_itemids=[]
                wb=openpyxl.load_workbook(mbpath)
                ws=wb['Template']
                row=7
                pskudatas=[]
                for pii_lsit in cur_pros:
                    cur_itemids.append(pii_lsit[0]['itemid'])
                    pskudatas.extend(pii_lsit)

                for pro in pskudatas:
                    pro['price']=int(phl*pro['price']*pbs)
                    pro['skuPirce']=int(phl*pro['skuPirce']*pbs)
                    allimgs=[pro['image']]
                    if pro['images']:
                        try:
                            allimgs.extend(json.loads(pro['images']))
                        except Exception as e:
                            pass

                    rol=1
                    try:
                        for ry in rys:
                            mbcol=ry[1]
                            smtcol=ry[2]
                            gd=ry[4]

                            if smtcol=='SKU图片网址':
                                rol+=1
                                continue
                            
                            if '无' not in smtcol and smtcol:
                                if smtcol=='SKU名称':
                                    if zjys.get(mbcol):
                                        ws.cell(row=row,column=rol).value=pro[zjys.get(mbcol)]
                                        if zjys.get(mbcol)=='sku1' and not pro['sku1']:
                                            ws.cell(row=row,column=rol).value='style'

                                elif smtcol=='主图网址':
                                    if len(allimgs)>0:
                                        ws.cell(row=row,column=rol).value=allimgs.pop(0)

                                else:
                                    ws.cell(row=row,column=rol).value=str(pro[smtys.get(smtcol)])
                            
                            else:
                                ws.cell(row=row,column=rol).value=gd
                                if gd=='size' and not pro['sku2']:
                                    ws.cell(row=row,column=rol).value=''

                            rol+=1
                        row+=1
                    except Exception as e:
                        logging.info(f'第{row}行,第{rol}列填写错误 =>{e}')

                file_path=f'{dir_path}/{self.bid}-{file_j:02d}_{mbid}-{j+1}-{len(cur_pros)}-{int(time.time())}.xlsx'
                wb.save(file_path)
                file_j+=1
                excel_datas.append({
                    'file_path':file_path,
                    'dc_itemids':cur_itemids,
                    'mbid':mbid
                })
                print(f'店铺:《{dpName}》,bid:{bid},mb:{mbid},第{j+1}份文件,导出 {len(cur_pros)} 个产品,成功保存至:《{file_path}》')
                if len(excel_datas)>=4:
                    break
            if dc_count>=count:
                logging.info(f'店铺:《{dpName}》,bid:{bid},当前提取数据:{dc_count},达到所需数量:{count},退出导出')
                break
            if len(excel_datas)>=4:
                logging.info(f'店铺:《{dpName}》,bid:{bid},当前提取数据:{dc_count},达到文件上限4份,退出导出')
                break
        return excel_datas

    async def yb_publish_compro(self):

        '''虾皮普货自动上数据'''
        shopid= self.basic_info['shopid']
        dc_type=self.basic_info['common_dc_type']
        if shopid:
            if not self.is_has_com_pro(dc_type,shopid):
                return {'code':0,'msg':'可导出数据为0','aff':0}

        browser=await openSunBrowser(self.basic_info,self.task_id)
        
        #browser =await openChrome()
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        page=await browser.newPage()
        aff=0
        purl='https://seller.shopee.co.id/portal/product-mass/import/upload'
        await repeat_goto(page,purl)
        
        sss=await self.check_login(page)
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        
        if not shopid:
            shopid=await js_req_shopid(page,self.basic_info)
            self.basic_info['shopid']=shopid
            self.ms.ExecNoQuery('update houtai set shopid=? where BrowserID=?',(shopid,self.bid))
            if not self.is_has_com_pro(dc_type,shopid):
                return {'code':0,'msg':'可导出数据为0','aff':0}

        need_dc_count= await get_POD_count(page,self.basic_info)
        if need_dc_count<=0:
            await self.close_browser(browser)
            return {'code':0,'msg':'产品上传达到上限','aff':0}
        
        logging.info(f'开始获取印尼普货侵权词...')
        rs_qqc=self.ms.ExecQuery('select qcontent from qqc where qtype=?',('印尼语普货',))
        self.qqkws=[r[0] for r in rs_qqc]
        logging.info(f'共获取 {len(self.qqkws)} 个印尼普货侵权词')

    
        excel_datas=self.get_com_pro(need_dc_count)
        logging.info(f'店铺:《{self.dpName}》,{self.bid},共生成 {len(excel_datas)} 个文件,开始循环上传')
        no_mbid=[]
        suc=0
        file_names=[]
        ydc_itemids_dict={}
        mbid_dict={}
        for j in range(len(excel_datas)):
            if j>=4:
                break
            dc_itemids=excel_datas[j]['dc_itemids']
            file_path=excel_datas[j]['file_path']
            mbid=excel_datas[j]['mbid']
            if mbid in no_mbid:
                logging.info(f'店铺:《{self.dpName}》,{self.bid},开始上传第 {j+1} 个文件,模版 {mbid} 需要更新,跳过')
                continue
            logging.info(f'店铺:《{self.dpName}》,{self.bid},开始上传第 {j+1} 个文件:《{file_path}》')

            upload_ipt=await wait_one_xpath(page,'//input[@class="eds-file-uploader uploader eds-upload__input"]',max_wait=120)
            await upload_ipt[0].uploadFile(file_path)
            file_name=os.path.basename(file_path)
            file_names.append(file_name)
            ydc_itemids_dict[file_name]=dc_itemids
            mbid_dict[file_name]=mbid
            await asyncio.sleep(5)

        res_reports=await get_xp_report(page,file_names,self.basic_info)
        for fff_nnn,res_report in res_reports.items():
            mbid=mbid_dict[fff_nnn]
            logging.info(f'店铺:《{self.dpName}》,{self.bid},文件 《{fff_nnn}》上传结束')
            rp_state='Successful'
            file_id=res_report['id']
            rp_status=res_report['record_status']
            suc_count=res_report['success_count']
            all_count=res_report['total_count']
            handled_count=res_report['handled_count']
            fail_count=all_count-suc_count
            ctime=timestamp_to_sql_datetime(res_report['ctime'])
            mtime=res_report['mtime']
            if mtime!=0:
                mtime=timestamp_to_sql_datetime(res_report['ctime'])
            else:
                mtime=None

            shopid=res_report['shop_id']
            
            if suc_count==0:
                rp_state='Unsuccessful'

            if rp_status==7 or handled_count==0:
                no_mbid.append(mbid)
                rp_state='Failed'
            
            if rp_state!='Successful':

                zds=['FileID','mbid','shopID','[all]','[suc]','[fail]','status','state','downloadPath',
                     'bid','bname','gname','create_time','mass_time']
                paras=[file_id,mbid,shopid,all_count,suc_count,fail_count,rp_state,rp_status,file_path,
                       self.bid,self.dpName,self.gname,ctime,mtime]
                now_time=int(time.time())
                cur_dc_itemids=ydc_itemids_dict[fff_nnn]
                aff000=0
                if dc_type==1:
                    for phitemid in cur_dc_itemids:
                        aff000+=self.ms.ExecNoQuery('update proshopeeph set daochu=0,daochuTime=? where itemid=?',(now_time,phitemid))
                aff=self.ms.merge_into('ShopeeReport',zds,paras,['FileID'],True)

                logging.info(f'店铺:《{self.dpName}》,{self.bid},文件 《{fff_nnn}》上传失败,登记错误报告:{aff},回溯:{aff000}')
            else:
                aff=0
                now_time=int(time.time())
                cur_dc_itemids=ydc_itemids_dict[fff_nnn]
                for phitemid in cur_dc_itemids:
                    if dc_type==1:
                        aff+=self.ms.ExecNoQuery('update proshopeeph set daochu=1,daochuTime=? where itemid=?',(now_time,phitemid))
                    else:
                        aff+=self.ms.ExecNoQuery(f"update proshopeeph set dc_shopids=dc_shopids+'|{shopid}',daochuTime=? where itemid=?",(now_time,phitemid))

                suc+=1
                logging.info(f'店铺:《{self.dpName}》,{self.bid},文件 《{fff_nnn}》上传成功,标记导出状态:{aff}')
                await asyncio.sleep(1)

        if dc_type==1:
            biid=self.basic_info['id']
            aff_dy=self.ms.ExecNoQuery('update proshopeeph set daochu=0 where daochu=? and datatype=1',(biid,))
            logging.info(f'店铺:《{self.dpName}》,{self.bid},回溯 {aff_dy} 个多余导出')  

        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':'执行成功','aff':suc}

    async def yb_get_order_and_stock(self):
        '''采集所有订单和最新售价'''
        browser = await openSunBrowser(self.basic_info,self.task_id)
        #browser=await openChrome()
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        page=await browser.newPage()
        url=f'https://seller.shopee.co.id/portal/sale/order'
        await repeat_goto(page,url)
        sss=await self.check_login(page)
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        
        await wait_one_xpath(page,'//div[@class="text-section"]',max_wait=180)
        msg=''
        aff=0
        aff_odder=await update_XPOrder(page,self.basic_info)
        
        if aff_odder is not None:
            tms.ExecNoQuery('update houtai set order_updated=1 where BrowserID=?',(self.bid,))
            aff+=1
        msg+='更新订单信息成功,' if aff_odder is not None else '更新订单信息失败,'

        aff_stock=await update_XPStock(page,self.basic_info)
        if aff_stock is not None:
            aff+=1
        msg+='更新产品库存成功,' if aff_stock is not None else '更新产品库存失败,'

        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':msg,'aff':aff}

    async def yb_moni_addkw2(self):
        '''虾皮增加广告词2'''

        #判断是否已经加入任务表
        ad_task_added=self.basic_info['ad_task_added']
        if ad_task_added==1:
            rs=self.ms.ExecQuery('select count(*) from ShopeeADTask where bid=? and ck_state=0',(self.bid,))
            if rs[0][0]==0:
                logging.info(f'店铺:《{self.dpName}》,{self.bid},今日所有词都已添加并检测完毕')
                return {'code':0,'msg':'所有词都已添加并检测完毕','aff':0}
        

        browser=await openSunBrowser(self.basic_info,self.task_id)
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        page=await browser.newPage()
        url=f'https://seller.shopee.co.id/portal/marketing/pas/index'
        await repeat_goto(page,url)
        sss=await self.check_login(page)
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        
        await wait_one_xpath(page,'//div[@class="export-button"]')

        if ad_task_added==0:
            logging.info(f'店铺:《{self.dpName}》,{self.bid},未进行增加任务,先进行任务增加...')
            await add_kw_to_adtask(page,self.basic_info)
        
        res_suc=0
        
        
        shopid=self.basic_info['shopid']
        if not shopid:
            shopid=await js_req_shopid(page,self.basic_info)
        rs_kws= self.ms.ExecQuerydict('select * from ShopeeADTask where shopid=? and ck_state=0 and action_type!=?',(shopid,'任务增加异常'))
        pid_kw_dict={}

        for r in rs_kws:
            pid=r['product_id']
            camp_id=r['campaign_id']
            kw= r['Search_Query']
            kw_ly=r['kw_type']
            action_type=r['action_type']

            if pid_kw_dict.get(pid):
                if action_type=='新增':
                    pid_kw_dict[pid]['add'].append(kw)
                elif action_type=='修改':
                    pid_kw_dict[pid]['edit'].append(kw)
            
            else:
                pid_kw_dict[pid]={}
                pid_kw_dict[pid]['add']=[]
                pid_kw_dict[pid]['edit']=[]
                pid_kw_dict[pid]['camp_id']=camp_id
                pid_kw_dict[pid]['bid_price']=400 if kw_ly=='出单词表' else 300
                if action_type=='新增':
                    pid_kw_dict[pid]['add'].append(kw)
                elif action_type=='修改':
                    pid_kw_dict[pid]['edit'].append(kw)


        pj=1
        for cur_itemid,vdd in pid_kw_dict.items():
            cur_campaign_id=vdd['camp_id']
            bid_price=vdd['bid_price']
            kws_edit_list=vdd['edit']
            kw_add=vdd['add']
            st_time,ed_time=calculate_timestamps2()
            purl=f'https://seller.shopee.co.id/portal/marketing/pas/product/manual/{cur_campaign_id}?from={st_time}&to={ed_time}&group=last_three_month'
            await repeat_goto(page,purl)
            el_total_page=await wait_one_xpath(page,'//span[@class="eds-pager__total"]')
            await wait_tc_xpath(page)
            total_page = await page.evaluate('(el) => el.textContent', el_total_page[0])
            total_page=int(total_page)

            logging.info(f'店铺:《{self.dpName}》,BrowserID:{self.bid},第{pj}个pid:{cur_itemid}, 需新增:{len(kw_add)},需修改:{len(kws_edit_list)}')

            for ppp in range(1,total_page+1):
                if len(kws_edit_list)==0:
                    break

                trs=await page.xpath('//div[@class="common-card card"]//div[@class="eds-table__fix-body eds-table__fix-left"]//table//tr')
                logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid,第{ppp}页,共加载{len(trs)} 个关键词')
                for tr in trs:
                    el_deleted=await tr.xpath('./td[2]//span[@class="deleted"]')
                    if el_deleted:
                        kws_edit_list=[]
                        break
                    
                    el_kwtxt= await tr.xpath('./td[2]//div[@class="ellipsis-content single"]')
                    if not el_kwtxt:
                        continue
                    hower_kw= await page.evaluate('(el) => el.textContent', el_kwtxt[0])
                    hower_kw=hower_kw.strip()

                    if hower_kw in kws_edit_list:
                        logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid,第 {ppp} 页,找到 :{hower_kw}')
                        el_adtype=await tr.xpath('./td[3]//div[@class="eds-selector__inner line-clamp--1"]')
                        nadt='Exact match'
                        logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid,《{hower_kw}》,更改广告类型至 Broad type => {nadt}')
                        await el_adtype[0].click({'delay':200})
                        await asyncio.sleep(3)
                        el_opt=await wait_one_xpath(page,f'//div[@class="eds-option"]//div[@class="item-title" and text()=" {nadt} " ]')
                        for qr_btn in el_opt:
                            try:
                                await qr_btn.click({'delay':200})
                                break
                            except Exception as e:
                                pass
                        await asyncio.sleep(3)
                        cur_time=datetime.datetime.now()
                        self.ms.ExecNoQuery(f'update ShopeeADTask set gt_state=1,update_time=? where product_id=? and Search_Query=?',(cur_time,cur_itemid,hower_kw))
                        kws_edit_list.remove(hower_kw)
                    
                el_next_btn=await page.xpath('//button[contains(@class,"eds-pager__button-next")]')
                await el_next_btn[0].click({'delay':200})
                await asyncio.sleep(3)

            sttt=get_three_time()
            st_time=sttt[0]
            ed_time=sttt[1]

            purl=f'https://seller.shopee.co.id/portal/marketing/pas/product/manual/{cur_campaign_id}?from={st_time}&to={ed_time}&group=last_three_month'
            
            kkj=1

            for addkw in kw_add:   
                try:
                    await repeat_goto(page,purl)
                    sss=await self.check_login(page)
                    if not sss:
                        await self.close_browser(browser)
                        return {'code':-2,'msg':'账户登录失败'}
                    wait_eddkw=0
                    while True:
                        try:
                            el_add_kw=await page.xpath('//div[@class="keywordActions"]')
                            if el_add_kw:
                                break
                        except Exception as e:
                            print(e)
                        await asyncio.sleep(1)
                        wait_eddkw+=1
                        if wait_eddkw>=60:
                            await repeat_goto(page,purl)
                            wait_eddkw=0
                    el_paused=await page.xpath('//span[@class="campaign-state paused"]')
                    if el_paused:
                        logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid,广告被暂停,退出增加')
                        break


                    await check_tc(page,'//div[@class="FULMadiY5u"]//div[text()="Maybe Later"]')
                    await el_add_kw[0].click({'delay':200})
                    await wait_one_xpath(page,'//h1[@class="header"]')
                    logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid,第{kkj}个广告词:《{addkw}》,开始搜索')
                    el_put=await page.xpath('//input[@placeholder="Type here to search for keywords to add"]')
                        
                    await el_put[0].type(addkw,{'delay': 100})
                    await asyncio.sleep(3)
                    await page.keyboard.press('Enter')
                    await asyncio.sleep(5)
                    mmmwww=0
                    
                    while True:
                        
                        elsss=await page.xpath(f'//div[@class="selector"]//span[@class="keyword" and contains(text(),"{addkw}")]')
                        if elsss:
                            break
                        mmmwww+=1
                        if mmmwww>10:
                            break
                        await asyncio.sleep(1)

                    await asyncio.sleep(3)
                    logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid,第{kkj}个广告词:《{addkw}》,检测是否可添加')
                    trs_add=await page.xpath('//div[@class="selector"]//tr[@class="eds-table__row"]')
                    if trs_add:
                        tr_one=trs_add[0]
                        el_searchkw=await tr_one.xpath(f'./td[1]//div[text()=" {addkw} "]')
                        await asyncio.sleep(1.5)
                        if el_searchkw:
                            el_isadded= await tr_one.xpath('./td[5]//*[text()=" Added "]')
                            if el_isadded:
                                print(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid,第{kkj}个广告词:《{addkw}》,已添加无需操作')
                            else:
                                el_add=await tr_one.xpath('./td[5]//*[text()=" Add "]')
                                if el_add:
                                    logging.info(f'《{addkw}》,点击添加')
                                    await asyncio.sleep(1.5)
                                    await el_add[0].click({'delay':200})
                                    logging.info(f'《{addkw}》,更改bid pirce')
                                    await asyncio.sleep(1.5)
                                    while True:
                                        el_ipt_bid_price=await page.xpath('//div[@class="bidPriceContent"]//input[1]')
                                        if el_ipt_bid_price:
                                            break
                                        else:
                                            el_add=await tr_one.xpath('./td[5]//*[text()=" Add "]')
                                            await el_add[0].click({'delay':200})

                                    await el_ipt_bid_price[0].click()  # 点击输入框
                                    await page.keyboard.down('Control')  # 按下 Ctrl 键（Mac 上使用 'Meta' 替代）
                                    await page.keyboard.press('A')  # 全选内容
                                    await page.keyboard.up('Control')  # 释放 Ctrl 键
                                    await page.keyboard.press('Backspace')  # 删除选中的内容
                                    await el_ipt_bid_price[0].type(f'{bid_price}',{'delay':200})
                                    await asyncio.sleep(1)
                                    logging.info(f'《{addkw}》,更改广告类型为Exact match')
                                    el_select=await page.xpath('//div[@class="action"]//div[@name="match-type-select"]')
                                    if el_select:
                                        await el_select[0].click({'delay':200})
                                        await asyncio.sleep(3)
                                        
                                        el_opt=await wait_one_xpath(page,'//div[@class="eds-option"]//div[@class="item-title" and text()=" Exact match " ]') 
                                        await el_opt[-1].click({'delay':200})
                                        await asyncio.sleep(3)
                                        el_btn_confim=await page.xpath('//div[@ads-type="keyword"]//span[text()="Confirm"]')
                                        await el_btn_confim[0].click({'delay':200})
                                        cur_time=datetime.datetime.now()
                                        self.ms.ExecNoQuery(f'update ShopeeADTask set gt_state=1,update_time=? where product_id=? and Search_Query=?',(cur_time,cur_itemid,addkw))
                                        res_suc+=1
                                        await asyncio.sleep(3)
        
                        else:
                            logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid,第{kkj}个广告词:《{addkw}》,搜索列表无该词...')
                    else:
                        logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid,第{kkj}个广告词:《{addkw}》,搜索结果为空...')

                except Exception as e:
                    logging.error(e)
                logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid,第{kkj}个广告词:《{addkw}》,添加完毕')
                kkj+=1


            await check_adtask(page,self.basic_info,cur_itemid,cur_campaign_id)
            pj+=1

        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':'执行成功','aff':res_suc}

    async def yb_moni_delkw(self,campids=None):
        '''虾皮删除广告词'''
        browser=await openSunBrowser(self.basic_info,self.task_id)
        if not browser:
            return {'code':-1,'msg':'启动浏览器失败'}
        page=await browser.newPage()
        url=f'https://seller.shopee.co.id/portal/marketing/pas/index'
        await repeat_goto(page,url)
        sss=await self.check_login(page)
        if not sss:
            await self.close_browser(browser)
            return {'code':-2,'msg':'账户登录失败'}
        await wait_one_xpath(page,'//div[@class="export-button"]')
        self.SPC_CDS,self.ck= await get_ck_and_spc_cds(page)
        logging.info(f'店铺:《{self.dpName}》,BrowserID:{self.bid},获取cookie成功,同时获取店铺SPC_CDS:{self.SPC_CDS}')
        campaign_dict0=await get_camps(page,self.basic_info)
        logging.info(f'店铺:《{self.dpName}》,BrowserID:{self.bid},共有 {len(campaign_dict0.keys())} 广告')
        if campids is None:
            campaign_dict=campaign_dict0
        else:
            campaign_dict={pid:camp_id for pid,camp_id in campids if campaign_dict0.get(pid)}

        logging.info(f'店铺:《{self.dpName}》,BrowserID:{self.bid},共有{len(campaign_dict.values())}个producdID需要广告优化...')
        
        res_suc=0
        pj=1
        #campaign_dict={'29061905212':'277411595'}
        for cur_itemid,cur_campaign_id in campaign_dict.items():

            logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},campaign_id:{cur_campaign_id},开始删除操作...')
            self.cpid=cur_itemid
            self.basic_info['pid']=cur_itemid
            sttt=get_three_time()
            st_time=sttt[0]
            ed_time=sttt[1]
            
            purl=f'https://seller.shopee.co.id/portal/marketing/pas/product/manual/{cur_campaign_id}?from={st_time}&to={ed_time}&group=last_three_month'

            await repeat_goto(page,purl)
            sss=await self.check_login(page)
            if not sss:
                await self.close_browser(browser)
                return {'code':-2,'msg':'账户登录失败'}
            await wait_one_xpath(page,'//div[@class="campaign-name"]',max_wait=60)
            await asyncio.sleep(3)
            
            st_time,ed_time=calculate_timestamps2()
            params={'SPC_CDS':self.SPC_CDS,'SPC_CDS_VER':2}
            kw_reports={}

            api_url='https://seller.shopee.co.id/api/pas/v1/product/manual/list_keyword_with_recommended_price/'
            post_data={"campaign_id":int(cur_campaign_id),"need_recommended_price":True,"header":{}}
            json_data= await make_request(page,api_url,params,post_data)
            if not json_data:
                await self.close_browser(browser)
                return {'code':-3,'msg':'获取广告词信息错误'}
            kw_kprs=json_data.get('data')
            if kw_kprs:
                krp_j=0
                for kw_kpr in kw_kprs:
                    if kw_kpr['keyword']['state']=='active':
                        cur_kw_info={}
                        curkw=kw_kpr['keyword']['keyword']
                        cur_kw_info['bid_price']=kw_kpr['keyword']['bid_price']/100000
                        cur_kw_info['match_type']=kw_kpr['keyword']['match_type']
                        cur_kw_info['state']=kw_kpr['keyword']['state']
                        kw_reports[curkw]=cur_kw_info
                        krp_j+=1
                logging.info(f'店铺:《{self.dpName}》,{self.bid},pid:{cur_itemid},获取广告词bid_price成功,共{len(kw_kprs)}个,其中active:{krp_j}个')
            else:
                logging.info(f'店铺:《{self.dpName}》,{self.bid},pid:{cur_itemid},广告词bid_price为空')

            api_url='https://seller.shopee.co.id/api/pas/v1/report/get/'
            post_data={"start_time":st_time,"end_time":ed_time,"campaign_type":"product",
                   "agg_type":"keyword","filter_params":{"campaign_id":int(cur_campaign_id)},"need_ratio":True,"header":{}}
            json_data= await make_request(page,api_url,params,post_data)
            if not json_data:
                await self.close_browser(browser)
                return {'code':-3,'msg':'获取广告词信息错误'}

            kw_zbs=json_data.get('data')
            if kw_zbs:
                zbs_j=0
                for kw_zb in kw_zbs:
                    curkw=kw_zb['key']
                    if kw_reports.get(curkw):
                        cur_kw_info=kw_reports[curkw]
                        cur_kw_info['CTR']=kw_zb['metrics']['ctr']
                        cur_kw_info['Clicks']=kw_zb['metrics']['click']
                        cur_kw_info['broad_gmv']=kw_zb['metrics']['broad_gmv']/100000
                        cur_kw_info['direct_gmv']=kw_zb['metrics']['direct_gmv']/100000
                        cur_kw_info['cost']=kw_zb['metrics']['cost']/100000
                        cur_kw_info['impression']=kw_zb['metrics']['impression']
                        kw_reports[curkw]=cur_kw_info
                        zbs_j+=1

                logging.info(f'店铺:《{self.dpName}》,{self.bid},pid:{cur_itemid},获取广告词报表参数成功,共{len(kw_zbs)}个,其中active:{zbs_j}个')
            else:
                logging.info(f'店铺:《{self.dpName}》,{self.bid},pid:{cur_itemid},广告词报表参数为空')


            cur_time=int(time.time())
            rs_ttt=self.ms.ExecQuery('select Search_Query,uploadTime from YN_AD_Info where Product_ID=?',(cur_itemid,))
            ttt_j=0
            for ccc_kw,upload_time in rs_ttt:
                ccc_kw=re.sub(r'[%.,/&+-]',' ',ccc_kw).strip().replace('  ',' ')
                if kw_reports.get(ccc_kw):
                    kw_reports[ccc_kw]['stay_time']=(cur_time-upload_time)/86400
                    ttt_j+=1

            logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},从数据库获取到 {len(rs_ttt)} 个词的时间,其中active:{ttt_j}个')

            kw_del=[]
            more_than_15=0
            kw_cansu_dict={}
            # with open(f'JSONDATA/kw_rp_{cur_itemid}.json','w',encoding='utf-8') as f:
            #     json.dump(kw_reports,f,ensure_ascii=False,indent=4)
            for rpkw,rpcs in kw_reports.items():
                if rpcs.get('CTR') is not None:
                    kw_gmv=rpcs['broad_gmv'] if rpcs['match_type']=='broad' else rpcs['direct_gmv']

                    if rpcs['CTR']<0.02 and rpcs['match_type']=='broad' and rpcs['Clicks']>=3 and kw_gmv==0:
                        kw_del.append(rpkw)
                        kw_cansu_dict[rpkw]=f"CTR:{rpcs['CTR']}<=0.02,Match Type:{rpcs['match_type']},clikcs:{rpcs['Clicks']}>=3,gmv:{kw_gmv}"
                    
                    elif rpcs['CTR']<0.05 and rpcs['match_type']=='exact' and rpcs['Clicks']>=6 and kw_gmv==0:
                        kw_del.append(rpkw)
                        kw_cansu_dict[rpkw]=f"CTR:{rpcs['CTR']}<=0.05,Match Type:{rpcs['match_type']},clikcs:{rpcs['Clicks']}>=6,gmv:{kw_gmv}"

                    elif rpcs['cost']>=30000 and kw_gmv==0 and rpcs['bid_price']==300:
                        kw_del.append(rpkw)
                        kw_cansu_dict[rpkw]=f"Expense:{rpcs['cost']}>=30000,gmv:{kw_gmv}=0,bid_price:{rpcs['bid_price']}=300"

                    elif rpcs['impression']>=100 and rpcs['Clicks']==0:
                        kw_del.append(rpkw)
                        kw_cansu_dict[rpkw]=f"impression:{rpcs['impression']}>=100,clikcs:{rpcs['Clicks']}=0"

                    elif rpcs['Clicks']==0 and rpcs.get('stay_time') and rpcs.get('stay_time')>=15:
                        more_than_15+=1
                        kw_del.append(rpkw)
                        kw_cansu_dict[rpkw]=f"clikcs:{rpcs['Clicks']}=0,创建时间:{rpcs['stay_time']:.2f}>=15"

                    elif rpcs['cost']>=100000 and kw_gmv==0 and rpcs['bid_price']>300:
                        kw_del.append(rpkw)
                        kw_cansu_dict[rpkw]=f"Expense:{rpcs['cost']}>=100000,gmv:{kw_gmv}=0,bid_price:{rpcs['bid_price']}>300"

            logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},有 {more_than_15} 个创建超过15天且0点击量')
            logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},活跃词共:{len(kw_reports.keys())}个')
            logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},需删除:{kw_del},共{len(kw_del)}个')

            if len(kw_del)==0:
                aff_del=self.ms.ExecNoQuery('update campaign set is_del_kw=1 where campaign_id=? and product_id=?',(cur_campaign_id,cur_itemid))
                logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},无需删除,标记删除状态:{aff_del}')
                pj+=1
                continue

            el_total_page=await wait_one_xpath(page,'//span[@class="eds-pager__total"]')
            await asyncio.sleep(5)
            await check_tc(page,'//div[@class="FULMadiY5u"]//div[text()="Maybe Later"]')
            total_page = await page.evaluate('(el) => el.textContent', el_total_page[0])
            total_page=int(total_page)
            logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},获取最大页数为:{total_page}')
            ppp=1
            while True:
                if len(kw_del)==0:
                    logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},删除列表已空')
                    break
                trs=await page.xpath('//div[@class="common-card card"]//div[@class="eds-table__fix-body eds-table__fix-left"]//table//tr')
                logging.info(f'店铺:《{self.dpName}》,{self.bid},第{ppp}页 共 {len(trs)} 个关键词')
                is_do_delete=False
                for tr in trs:

                    el_kwtxt= await tr.xpath('./td[2]//div[@class="ellipsis-content single"]')
                    if not el_kwtxt:
                        continue
                    hower_kw= await page.evaluate('(el) => el.textContent', el_kwtxt[0])
                    hower_kw=hower_kw.strip()
                    if hower_kw in kw_del:
                        logging.info(f'店铺:《{self.dpName}》,{self.bid},第 {ppp} 页,找到 :{hower_kw}')
                        el_deleted=await tr.xpath('./td[2]//span[@class="deleted"]')
                        if el_deleted:
                            logging.info(f'店铺:《{self.dpName}》,{self.bid},第 {ppp} 页,{hower_kw} 已被删除,无需操作')
                            kw_del.remove(hower_kw)
                        else:
                            while True:
                                await tr.hover()
                                el_del=await page.xpath(f'//div[@class="item-delete {hower_kw}"]')
                                if el_del:
                                    await el_del[0].click({'delay':200})
                                    el_qr_btn=await page.xpath('//div[@class="shopee-modal__footer"]//button[2]')
                                    if el_qr_btn:
                                        await el_qr_btn[0].click({'delay':200})
                                        await asyncio.sleep(3)
                                        is_do_delete=True
                                        del_time=datetime.datetime.now()
                                        zds_del=['BrowserID','DpName','GroupName','Product_ID','Search_Query','is_added','is_del','delTime','del_des']
                                        para_del=[self.bid,self.dpName,self.gname,cur_itemid,hower_kw,-2,1,del_time,kw_cansu_dict.get(hower_kw)]
                                        zd_on_del=['Product_ID','Search_Query']
                                        aff_ddd=self.ms.merge_into('yn_ad_csv',zds_del,para_del,zd_on_del)
                                        break
                                else:
                                    logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},campaign_id:{cur_campaign_id},可能只剩一个广告词,无法删除')
                                    break
                              
                            kw_del.remove(hower_kw)
                            res_suc+=1
                            logging.info(f'店铺:《{self.dpName}》,{self.bid},第 {ppp} 页,{hower_kw} 成功删除,剩余删除数:{len(kw_del)}')
                            upload_adkw_action(cur_itemid,cur_campaign_id,hower_kw,'delete',kw_cansu_dict.get(hower_kw),self.basic_info)
                            await asyncio.sleep(2)

                    if len(kw_del)==0:
                        break
                if len(kw_del)==0:
                    aff_del=self.ms.ExecNoQuery('update campaign set is_del_kw=1 where campaign_id=? and product_id=?',(cur_campaign_id,cur_itemid))
                    logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},campaign_id:{cur_campaign_id},全部删除完毕,标记删除状态:{aff_del}')
                    break
                
                if not is_do_delete:
                    el_next_btn=await page.xpath('//button[contains(@class,"eds-pager__button-next")]')
                    await el_next_btn[0].click({'delay':200})
                    await asyncio.sleep(5)
                    ppp+=1
                if ppp>total_page:
                    logging.info(f'店铺:《{self.dpName}》,{self.bid},第{pj}个pid:{cur_itemid},广告词词抵达最后一页退出...')
                    break
            pj+=1

        await page.close()
        await self.close_browser(browser)
        return {'code':0,'msg':'执行成功','aff':res_suc}
         

    def start_task(self,task_id):
        rw_name=Task_Name_dict[task_id]
        fun_name=Task_Fuc_dict[task_id]
        self.task_id=task_id
        self.rw_name=rw_name
        bname=self.dpName
        toady_date=datetime.datetime.today().strftime('%Y-%m-%d')
        try:
            func = getattr(self, fun_name)
            if inspect.iscoroutinefunction(func):
                
                if task_id==17:
                    current_date = datetime.datetime.now().strftime("%Y_%m_%d")
                    cur_bb_bid_path=f'{PRO_AD_DIR}/详情报表_{current_date}/{self.bid}'
                    if not os.path.exists(cur_bb_bid_path):
                        os.makedirs(cur_bb_bid_path)
                    self.bb_save_path=cur_bb_bid_path
                    logging.info(f'店铺:《{self.dpName}》,{self.bid},今日详情报表目录 《{self.bb_save_path}》')
                res=asyncio.run(func())
            else:
                res=func()

            code=res['code']
            msg=res['msg']
            if code==0:
                is_suc=True
                if task_id==17:
                    sql_bb=f'''select count(*) from campaign where is_download_bb=0 and bid=? 
                    and is_on=1'''
                    sql_bbadid='select count(*) from houtai where isbbadid=1 and browserid=?'
                    rs_bbc2=self.ms.ExecQuery(sql_bbadid,(self.bid,))
                    rs_bbc=self.ms.ExecQuery(sql_bb,(self.bid,))
                    if rs_bbc[0][0]>0 or rs_bbc2[0][0]==0:
                        is_suc=False
                
                if not is_suc:
                    logging.info(f'店铺:《{self.dpName}》,{self.bid} 任务:《{rw_name}》,部分未完成')
                else:
                    end_zds=['bid','task_id','task_name','bname','gname','state']
                    end_params=[self.bid,task_id,rw_name,self.dpName,self.gname,1]
                    aff_rw=tms.merge_into('taskStatus',end_zds,end_params,['bid','task_id'],True)
                    if task_id==17:
                        sql_bb_ff=f'''select count(*) from campaign where is_download_bb=1 and bid=? 
                            and is_on=1'''
                        rs_bb_ff=self.ms.ExecQuery(sql_bb_ff,(self.bid,))
                        txt_file=f'{self.bb_save_path}/1.txt'
                        with open(txt_file,'w',encoding='utf-8') as f:
                            f.write(str(rs_bb_ff[0][0]))
                        logging.info(f'店铺:《{self.dpName}》,{self.bid},记录报表今天下载全部完成共{rs_bb_ff[0][0]} 个,创建txt文件:《{txt_file}》')
                    logging.info(f'店铺:《{self.dpName}》,{self.bid} 任务:《{rw_name}》,{msg}:{aff_rw}')
            else:
                
                if task_id in (18,25,27):
                    ad_task_zd_dict={18:'ad_task_added',25:'ad_task_edited',27:'ad_task_deleted'}
                    ad_task_zd=ad_task_zd_dict[task_id]
                    ad_type_dict={18:'新增',25:'修改',27:'删除'}
                    act_zd=ad_type_dict[task_id]
                    
                    rs_ad_add=self.ms.ExecQuery(f'select count(*) from houtai where {ad_task_zd}=1 and BrowserID=?',(self.bid,))
                    if rs_ad_add[0][0]==0:
                        ad_zds=['bid','shopid','product_id','Search_Query','BName','GroupName','userName',
                                'action_type','SJBM','YYBM','action_des','task_date']
                        ad_paras=[self.bid,self.shopid,self.bid,toady_date,self.dpName,self.gname,self.userName,
                                f'任务增加异常({act_zd})',self.sjbm,self.yybm,msg,toady_date]
                        self.ms.merge_into('ShopeeADTask',ad_zds,ad_paras,['product_id','Search_Query','action_type'],True)
                else:
                    err_zds=['bid','task_id','task_name','bname','gname','state','err_msg','is_cl']
                    err_params=[self.bid,task_id,rw_name,self.dpName,self.gname,0,msg,0]
                    self.ms.merge_into('taskStatus',err_zds,err_params,['bid','task_id'],True)
                logging.info(f'店铺:《{self.dpName}》,{self.bid} 任务:《{rw_name}》,{msg}')

            return res
        except Exception as e:
            close_SunBrowser(self.bid,task_id)
            traceback.print_exc()
            if task_id in (18,25,27):
                ad_task_zd_dict={18:'ad_task_added',25:'ad_task_edited',27:'ad_task_deleted'}
                ad_task_zd=ad_task_zd_dict[task_id]
                ad_type_dict={18:'新增',25:'修改',27:'删除'}
                act_zd=ad_type_dict[task_id]
                rs_ad_add=self.ms.ExecQuery(f'select count(*) from houtai where {ad_task_zd}=1 and BrowserID=?',(self.bid,))
                if rs_ad_add[0][0]==0:
                    ad_zds=['bid','shopid','product_id','Search_Query','BName','GroupName','userName',
                            'action_type','SJBM','YYBM','action_des','task_date']
                    ad_paras=[self.bid,self.shopid,self.bid,toady_date,self.dpName,self.gname,self.userName,
                                f'任务增加异常({act_zd})',self.sjbm,self.yybm,str(e),toady_date]
                    self.ms.merge_into('ShopeeADTask',ad_zds,ad_paras,['product_id','Search_Query','action_type'],True)
            else:
                err_zds=['bid','task_id','task_name','bname','gname','state','err_msg','is_cl']
                err_params=[self.bid,task_id,rw_name,self.dpName,self.gname,0,str(e),0]
                self.ms.merge_into('taskStatus',err_zds,err_params,['bid','task_id'],True)
            logging.error(f'店铺:《{self.dpName}》,{self.bid} 任务:《{rw_name}》,出错 => {e}')